xmlschemas.c 801 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766
  1. /*
  2. * schemas.c : implementation of the XML Schema handling and
  3. * schema validity checking
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Daniel Veillard <veillard@redhat.com>
  8. */
  9. /*
  10. * TODO:
  11. * - when types are redefined in includes, check that all
  12. * types in the redef list are equal
  13. * -> need a type equality operation.
  14. * - if we don't intend to use the schema for schemas, we
  15. * need to validate all schema attributes (ref, type, name)
  16. * against their types.
  17. * - Eliminate item creation for: ??
  18. *
  19. * URGENT TODO:
  20. * - For xsi-driven schema acquisition, augment the IDCs after every
  21. * acquisition episode (xmlSchemaAugmentIDC).
  22. *
  23. * NOTES:
  24. * - Elimated item creation for: <restriction>, <extension>,
  25. * <simpleContent>, <complexContent>, <list>, <union>
  26. *
  27. * PROBLEMS:
  28. * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
  29. * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
  30. * XPath will have trouble to resolve to this namespace, since not known.
  31. *
  32. *
  33. * CONSTRAINTS:
  34. *
  35. * Schema Component Constraint:
  36. * All Group Limited (cos-all-limited)
  37. * Status: complete
  38. * (1.2)
  39. * In xmlSchemaGroupDefReferenceTermFixup() and
  40. * (2)
  41. * In xmlSchemaParseModelGroup()
  42. * TODO: Actually this should go to component-level checks,
  43. * but is done here due to performance. Move it to an other layer
  44. * is schema construction via an API is implemented.
  45. */
  46. #define IN_LIBXML
  47. #include "libxml.h"
  48. #ifdef LIBXML_SCHEMAS_ENABLED
  49. #include <string.h>
  50. #include <libxml/xmlmemory.h>
  51. #include <libxml/parser.h>
  52. #include <libxml/parserInternals.h>
  53. #include <libxml/hash.h>
  54. #include <libxml/uri.h>
  55. #include <libxml/xmlschemas.h>
  56. #include <libxml/schemasInternals.h>
  57. #include <libxml/xmlschemastypes.h>
  58. #include <libxml/xmlautomata.h>
  59. #include <libxml/xmlregexp.h>
  60. #include <libxml/dict.h>
  61. #include <libxml/encoding.h>
  62. #include <libxml/xmlIO.h>
  63. #ifdef LIBXML_PATTERN_ENABLED
  64. #include <libxml/pattern.h>
  65. #endif
  66. #ifdef LIBXML_READER_ENABLED
  67. #include <libxml/xmlreader.h>
  68. #endif
  69. /* #define DEBUG 1 */
  70. /* #define DEBUG_CONTENT 1 */
  71. /* #define DEBUG_TYPE 1 */
  72. /* #define DEBUG_CONTENT_REGEXP 1 */
  73. /* #define DEBUG_AUTOMATA 1 */
  74. /* #define DEBUG_IDC */
  75. /* #define DEBUG_IDC_NODE_TABLE */
  76. /* #define WXS_ELEM_DECL_CONS_ENABLED */
  77. #ifdef DEBUG_IDC
  78. #ifndef DEBUG_IDC_NODE_TABLE
  79. #define DEBUG_IDC_NODE_TABLE
  80. #endif
  81. #endif
  82. /* #define ENABLE_PARTICLE_RESTRICTION 1 */
  83. #define ENABLE_REDEFINE
  84. /* #define ENABLE_NAMED_LOCALS */
  85. /* #define ENABLE_IDC_NODE_TABLES_TEST */
  86. #define DUMP_CONTENT_MODEL
  87. #ifdef LIBXML_READER_ENABLED
  88. /* #define XML_SCHEMA_READER_ENABLED */
  89. #endif
  90. #define UNBOUNDED (1 << 30)
  91. #define TODO \
  92. xmlGenericError(xmlGenericErrorContext, \
  93. "Unimplemented block at %s:%d\n", \
  94. __FILE__, __LINE__);
  95. #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  96. /*
  97. * The XML Schemas namespaces
  98. */
  99. static const xmlChar *xmlSchemaNs = (const xmlChar *)
  100. "http://www.w3.org/2001/XMLSchema";
  101. static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  102. "http://www.w3.org/2001/XMLSchema-instance";
  103. static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  104. "http://www.w3.org/2000/xmlns/";
  105. /*
  106. * Come casting macros.
  107. */
  108. #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  109. #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  110. #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  111. #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  112. #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  113. #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  114. #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  115. #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  116. #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  117. #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  118. #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  119. #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  120. #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  121. #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  122. #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  123. #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  124. #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  125. /*
  126. * Macros to query common properties of components.
  127. */
  128. #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  129. #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  130. /*
  131. * Macros for element declarations.
  132. */
  133. #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  134. #define WXS_SUBST_HEAD(item) (item)->refDecl
  135. /*
  136. * Macros for attribute declarations.
  137. */
  138. #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  139. /*
  140. * Macros for attribute uses.
  141. */
  142. #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
  143. #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  144. #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  145. #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  146. /*
  147. * Macros for attribute groups.
  148. */
  149. #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  150. #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  151. /*
  152. * Macros for particles.
  153. */
  154. #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  155. #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  156. #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  157. #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  158. /*
  159. * Macros for model groups definitions.
  160. */
  161. #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  162. /*
  163. * Macros for model groups.
  164. */
  165. #define WXS_IS_MODEL_GROUP(i) \
  166. (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  167. ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  168. ((i)->type == XML_SCHEMA_TYPE_ALL))
  169. #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  170. /*
  171. * Macros for schema buckets.
  172. */
  173. #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  174. ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  175. #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  176. ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  177. #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  178. #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  179. /*
  180. * Macros for complex/simple types.
  181. */
  182. #define WXS_IS_ANYTYPE(i) \
  183. (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  184. ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  185. #define WXS_IS_COMPLEX(i) \
  186. (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  187. ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  188. #define WXS_IS_SIMPLE(item) \
  189. ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  190. ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  191. (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  192. #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  193. (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  194. ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  195. #define WXS_IS_RESTRICTION(t) \
  196. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  197. #define WXS_IS_EXTENSION(t) \
  198. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  199. #define WXS_IS_TYPE_NOT_FIXED(i) \
  200. (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  201. (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  202. #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  203. (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  204. (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  205. #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  206. #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  207. /*
  208. * Macros for exclusively for complex types.
  209. */
  210. #define WXS_HAS_COMPLEX_CONTENT(item) \
  211. ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  212. (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  213. (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  214. #define WXS_HAS_SIMPLE_CONTENT(item) \
  215. ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  216. (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  217. #define WXS_HAS_MIXED_CONTENT(item) \
  218. (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  219. #define WXS_EMPTIABLE(t) \
  220. (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  221. #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  222. #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  223. #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  224. /*
  225. * Macros for exclusively for simple types.
  226. */
  227. #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  228. #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  229. #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  230. #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  231. /*
  232. * Misc parser context macros.
  233. */
  234. #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  235. #define WXS_HAS_BUCKETS(ctx) \
  236. ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  237. (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  238. #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  239. #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  240. #define WXS_SCHEMA(ctx) (ctx)->schema
  241. #define WXS_ADD_LOCAL(ctx, item) \
  242. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  243. #define WXS_ADD_GLOBAL(ctx, item) \
  244. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  245. #define WXS_ADD_PENDING(ctx, item) \
  246. xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  247. /*
  248. * xmlSchemaItemList macros.
  249. */
  250. #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  251. /*
  252. * Misc macros.
  253. */
  254. #define IS_SCHEMA(node, type) \
  255. ((node != NULL) && (node->ns != NULL) && \
  256. (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  257. (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  258. #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  259. /*
  260. * Since we put the default/fixed values into the dict, we can
  261. * use pointer comparison for those values.
  262. * REMOVED: (xmlStrEqual((v1), (v2)))
  263. */
  264. #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  265. #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  266. #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  267. #define HFAILURE if (res == -1) goto exit_failure;
  268. #define HERROR if (res != 0) goto exit_error;
  269. #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  270. /*
  271. * Some flags used for various schema constraints.
  272. */
  273. #define SUBSET_RESTRICTION 1<<0
  274. #define SUBSET_EXTENSION 1<<1
  275. #define SUBSET_SUBSTITUTION 1<<2
  276. #define SUBSET_LIST 1<<3
  277. #define SUBSET_UNION 1<<4
  278. typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  279. typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  280. typedef struct _xmlSchemaItemList xmlSchemaItemList;
  281. typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  282. struct _xmlSchemaItemList {
  283. void **items; /* used for dynamic addition of schemata */
  284. int nbItems; /* used for dynamic addition of schemata */
  285. int sizeItems; /* used for dynamic addition of schemata */
  286. };
  287. #define XML_SCHEMA_CTXT_PARSER 1
  288. #define XML_SCHEMA_CTXT_VALIDATOR 2
  289. typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  290. typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  291. struct _xmlSchemaAbstractCtxt {
  292. int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  293. };
  294. typedef struct _xmlSchemaBucket xmlSchemaBucket;
  295. typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  296. #define XML_SCHEMA_SCHEMA_MAIN 0
  297. #define XML_SCHEMA_SCHEMA_IMPORT 1
  298. #define XML_SCHEMA_SCHEMA_INCLUDE 2
  299. #define XML_SCHEMA_SCHEMA_REDEFINE 3
  300. /**
  301. * xmlSchemaSchemaRelation:
  302. *
  303. * Used to create a graph of schema relationships.
  304. */
  305. typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  306. typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  307. struct _xmlSchemaSchemaRelation {
  308. xmlSchemaSchemaRelationPtr next;
  309. int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  310. const xmlChar *importNamespace;
  311. xmlSchemaBucketPtr bucket;
  312. };
  313. #define XML_SCHEMA_BUCKET_MARKED 1<<0
  314. #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  315. struct _xmlSchemaBucket {
  316. int type;
  317. int flags;
  318. const xmlChar *schemaLocation;
  319. const xmlChar *origTargetNamespace;
  320. const xmlChar *targetNamespace;
  321. xmlDocPtr doc;
  322. xmlSchemaSchemaRelationPtr relations;
  323. int located;
  324. int parsed;
  325. int imported;
  326. int preserveDoc;
  327. xmlSchemaItemListPtr globals; /* Global components. */
  328. xmlSchemaItemListPtr locals; /* Local components. */
  329. };
  330. /**
  331. * xmlSchemaImport:
  332. * (extends xmlSchemaBucket)
  333. *
  334. * Reflects a schema. Holds some information
  335. * about the schema and its toplevel components. Duplicate
  336. * toplevel components are not checked at this level.
  337. */
  338. typedef struct _xmlSchemaImport xmlSchemaImport;
  339. typedef xmlSchemaImport *xmlSchemaImportPtr;
  340. struct _xmlSchemaImport {
  341. int type; /* Main OR import OR include. */
  342. int flags;
  343. const xmlChar *schemaLocation; /* The URI of the schema document. */
  344. /* For chameleon includes, @origTargetNamespace will be NULL */
  345. const xmlChar *origTargetNamespace;
  346. /*
  347. * For chameleon includes, @targetNamespace will be the
  348. * targetNamespace of the including schema.
  349. */
  350. const xmlChar *targetNamespace;
  351. xmlDocPtr doc; /* The schema node-tree. */
  352. /* @relations will hold any included/imported/redefined schemas. */
  353. xmlSchemaSchemaRelationPtr relations;
  354. int located;
  355. int parsed;
  356. int imported;
  357. int preserveDoc;
  358. xmlSchemaItemListPtr globals;
  359. xmlSchemaItemListPtr locals;
  360. /* The imported schema. */
  361. xmlSchemaPtr schema;
  362. };
  363. /*
  364. * (extends xmlSchemaBucket)
  365. */
  366. typedef struct _xmlSchemaInclude xmlSchemaInclude;
  367. typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  368. struct _xmlSchemaInclude {
  369. int type;
  370. int flags;
  371. const xmlChar *schemaLocation;
  372. const xmlChar *origTargetNamespace;
  373. const xmlChar *targetNamespace;
  374. xmlDocPtr doc;
  375. xmlSchemaSchemaRelationPtr relations;
  376. int located;
  377. int parsed;
  378. int imported;
  379. int preserveDoc;
  380. xmlSchemaItemListPtr globals; /* Global components. */
  381. xmlSchemaItemListPtr locals; /* Local components. */
  382. /* The owning main or import schema bucket. */
  383. xmlSchemaImportPtr ownerImport;
  384. };
  385. /**
  386. * xmlSchemaBasicItem:
  387. *
  388. * The abstract base type for schema components.
  389. */
  390. typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  391. typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  392. struct _xmlSchemaBasicItem {
  393. xmlSchemaTypeType type;
  394. };
  395. /**
  396. * xmlSchemaAnnotItem:
  397. *
  398. * The abstract base type for annotated schema components.
  399. * (Extends xmlSchemaBasicItem)
  400. */
  401. typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  402. typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  403. struct _xmlSchemaAnnotItem {
  404. xmlSchemaTypeType type;
  405. xmlSchemaAnnotPtr annot;
  406. };
  407. /**
  408. * xmlSchemaTreeItem:
  409. *
  410. * The abstract base type for tree-like structured schema components.
  411. * (Extends xmlSchemaAnnotItem)
  412. */
  413. typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  414. typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  415. struct _xmlSchemaTreeItem {
  416. xmlSchemaTypeType type;
  417. xmlSchemaAnnotPtr annot;
  418. xmlSchemaTreeItemPtr next;
  419. xmlSchemaTreeItemPtr children;
  420. };
  421. #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  422. /**
  423. * xmlSchemaAttributeUsePtr:
  424. *
  425. * The abstract base type for tree-like structured schema components.
  426. * (Extends xmlSchemaTreeItem)
  427. */
  428. typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  429. typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  430. struct _xmlSchemaAttributeUse {
  431. xmlSchemaTypeType type;
  432. xmlSchemaAnnotPtr annot;
  433. xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  434. /*
  435. * The attr. decl. OR a QName-ref. to an attr. decl. OR
  436. * a QName-ref. to an attribute group definition.
  437. */
  438. xmlSchemaAttributePtr attrDecl;
  439. int flags;
  440. xmlNodePtr node;
  441. int occurs; /* required, optional */
  442. const xmlChar * defValue;
  443. xmlSchemaValPtr defVal;
  444. };
  445. /**
  446. * xmlSchemaAttributeUseProhibPtr:
  447. *
  448. * A helper component to reflect attribute prohibitions.
  449. * (Extends xmlSchemaBasicItem)
  450. */
  451. typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  452. typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  453. struct _xmlSchemaAttributeUseProhib {
  454. xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  455. xmlNodePtr node;
  456. const xmlChar *name;
  457. const xmlChar *targetNamespace;
  458. int isRef;
  459. };
  460. /**
  461. * xmlSchemaRedef:
  462. */
  463. typedef struct _xmlSchemaRedef xmlSchemaRedef;
  464. typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  465. struct _xmlSchemaRedef {
  466. xmlSchemaRedefPtr next;
  467. xmlSchemaBasicItemPtr item; /* The redefining component. */
  468. xmlSchemaBasicItemPtr reference; /* The referencing component. */
  469. xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  470. const xmlChar *refName; /* The name of the to-be-redefined component. */
  471. const xmlChar *refTargetNs; /* The target namespace of the
  472. to-be-redefined comp. */
  473. xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  474. };
  475. /**
  476. * xmlSchemaConstructionCtxt:
  477. */
  478. typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  479. typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  480. struct _xmlSchemaConstructionCtxt {
  481. xmlSchemaPtr mainSchema; /* The main schema. */
  482. xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  483. xmlDictPtr dict;
  484. xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  485. /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  486. xmlSchemaBucketPtr bucket; /* The current schema bucket */
  487. xmlSchemaItemListPtr pending; /* All Components of all schemas that
  488. need to be fixed. */
  489. xmlHashTablePtr substGroups;
  490. xmlSchemaRedefPtr redefs;
  491. xmlSchemaRedefPtr lastRedef;
  492. };
  493. #define XML_SCHEMAS_PARSE_ERROR 1
  494. #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  495. struct _xmlSchemaParserCtxt {
  496. int type;
  497. void *errCtxt; /* user specific error context */
  498. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  499. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  500. int err;
  501. int nberrors;
  502. xmlStructuredErrorFunc serror;
  503. xmlSchemaConstructionCtxtPtr constructor;
  504. int ownsConstructor; /* TODO: Move this to parser *flags*. */
  505. /* xmlSchemaPtr topschema; */
  506. /* xmlHashTablePtr namespaces; */
  507. xmlSchemaPtr schema; /* The main schema in use */
  508. int counter;
  509. const xmlChar *URL;
  510. xmlDocPtr doc;
  511. int preserve; /* Whether the doc should be freed */
  512. const char *buffer;
  513. int size;
  514. /*
  515. * Used to build complex element content models
  516. */
  517. xmlAutomataPtr am;
  518. xmlAutomataStatePtr start;
  519. xmlAutomataStatePtr end;
  520. xmlAutomataStatePtr state;
  521. xmlDictPtr dict; /* dictionnary for interned string names */
  522. xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  523. int options;
  524. xmlSchemaValidCtxtPtr vctxt;
  525. int isS4S;
  526. int isRedefine;
  527. int xsiAssemble;
  528. int stop; /* If the parser should stop; i.e. a critical error. */
  529. const xmlChar *targetNamespace;
  530. xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  531. xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  532. int redefCounter; /* Used for redefinitions. */
  533. xmlSchemaItemListPtr attrProhibs;
  534. };
  535. /**
  536. * xmlSchemaQNameRef:
  537. *
  538. * A component reference item (not a schema component)
  539. * (Extends xmlSchemaBasicItem)
  540. */
  541. typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  542. typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  543. struct _xmlSchemaQNameRef {
  544. xmlSchemaTypeType type;
  545. xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  546. xmlSchemaTypeType itemType;
  547. const xmlChar *name;
  548. const xmlChar *targetNamespace;
  549. xmlNodePtr node;
  550. };
  551. /**
  552. * xmlSchemaParticle:
  553. *
  554. * A particle component.
  555. * (Extends xmlSchemaTreeItem)
  556. */
  557. typedef struct _xmlSchemaParticle xmlSchemaParticle;
  558. typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  559. struct _xmlSchemaParticle {
  560. xmlSchemaTypeType type;
  561. xmlSchemaAnnotPtr annot;
  562. xmlSchemaTreeItemPtr next; /* next particle */
  563. xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  564. a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  565. etc.) */
  566. int minOccurs;
  567. int maxOccurs;
  568. xmlNodePtr node;
  569. };
  570. /**
  571. * xmlSchemaModelGroup:
  572. *
  573. * A model group component.
  574. * (Extends xmlSchemaTreeItem)
  575. */
  576. typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  577. typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  578. struct _xmlSchemaModelGroup {
  579. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  580. xmlSchemaAnnotPtr annot;
  581. xmlSchemaTreeItemPtr next; /* not used */
  582. xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  583. xmlNodePtr node;
  584. };
  585. #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  586. #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  587. /**
  588. * xmlSchemaModelGroupDef:
  589. *
  590. * A model group definition component.
  591. * (Extends xmlSchemaTreeItem)
  592. */
  593. typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  594. typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  595. struct _xmlSchemaModelGroupDef {
  596. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  597. xmlSchemaAnnotPtr annot;
  598. xmlSchemaTreeItemPtr next; /* not used */
  599. xmlSchemaTreeItemPtr children; /* the "model group" */
  600. const xmlChar *name;
  601. const xmlChar *targetNamespace;
  602. xmlNodePtr node;
  603. int flags;
  604. };
  605. typedef struct _xmlSchemaIDC xmlSchemaIDC;
  606. typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  607. /**
  608. * xmlSchemaIDCSelect:
  609. *
  610. * The identity-constraint "field" and "selector" item, holding the
  611. * XPath expression.
  612. */
  613. typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  614. typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  615. struct _xmlSchemaIDCSelect {
  616. xmlSchemaIDCSelectPtr next;
  617. xmlSchemaIDCPtr idc;
  618. int index; /* an index position if significant for IDC key-sequences */
  619. const xmlChar *xpath; /* the XPath expression */
  620. void *xpathComp; /* the compiled XPath expression */
  621. };
  622. /**
  623. * xmlSchemaIDC:
  624. *
  625. * The identity-constraint definition component.
  626. * (Extends xmlSchemaAnnotItem)
  627. */
  628. struct _xmlSchemaIDC {
  629. xmlSchemaTypeType type;
  630. xmlSchemaAnnotPtr annot;
  631. xmlSchemaIDCPtr next;
  632. xmlNodePtr node;
  633. const xmlChar *name;
  634. const xmlChar *targetNamespace;
  635. xmlSchemaIDCSelectPtr selector;
  636. xmlSchemaIDCSelectPtr fields;
  637. int nbFields;
  638. xmlSchemaQNameRefPtr ref;
  639. };
  640. /**
  641. * xmlSchemaIDCAug:
  642. *
  643. * The augmented IDC information used for validation.
  644. */
  645. typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  646. typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  647. struct _xmlSchemaIDCAug {
  648. xmlSchemaIDCAugPtr next; /* next in a list */
  649. xmlSchemaIDCPtr def; /* the IDC definition */
  650. int keyrefDepth; /* the lowest tree level to which IDC
  651. tables need to be bubbled upwards */
  652. };
  653. /**
  654. * xmlSchemaPSVIIDCKeySequence:
  655. *
  656. * The key sequence of a node table item.
  657. */
  658. typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  659. typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  660. struct _xmlSchemaPSVIIDCKey {
  661. xmlSchemaTypePtr type;
  662. xmlSchemaValPtr val;
  663. };
  664. /**
  665. * xmlSchemaPSVIIDCNode:
  666. *
  667. * The node table item of a node table.
  668. */
  669. typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  670. typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  671. struct _xmlSchemaPSVIIDCNode {
  672. xmlNodePtr node;
  673. xmlSchemaPSVIIDCKeyPtr *keys;
  674. int nodeLine;
  675. int nodeQNameID;
  676. };
  677. /**
  678. * xmlSchemaPSVIIDCBinding:
  679. *
  680. * The identity-constraint binding item of the [identity-constraint table].
  681. */
  682. typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  683. typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  684. struct _xmlSchemaPSVIIDCBinding {
  685. xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  686. xmlSchemaIDCPtr definition; /* the IDC definition */
  687. xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  688. int nbNodes; /* number of entries in the node table */
  689. int sizeNodes; /* size of the node table */
  690. xmlSchemaItemListPtr dupls;
  691. };
  692. #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  693. #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  694. #define XPATH_STATE_OBJ_MATCHES -2
  695. #define XPATH_STATE_OBJ_BLOCKED -3
  696. typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  697. typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  698. /**
  699. * xmlSchemaIDCStateObj:
  700. *
  701. * The state object used to evaluate XPath expressions.
  702. */
  703. typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  704. typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  705. struct _xmlSchemaIDCStateObj {
  706. int type;
  707. xmlSchemaIDCStateObjPtr next; /* next if in a list */
  708. int depth; /* depth of creation */
  709. int *history; /* list of (depth, state-id) tuples */
  710. int nbHistory;
  711. int sizeHistory;
  712. xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  713. matcher */
  714. xmlSchemaIDCSelectPtr sel;
  715. void *xpathCtxt;
  716. };
  717. #define IDC_MATCHER 0
  718. /**
  719. * xmlSchemaIDCMatcher:
  720. *
  721. * Used to evaluate IDC selectors (and fields).
  722. */
  723. struct _xmlSchemaIDCMatcher {
  724. int type;
  725. int depth; /* the tree depth at creation time */
  726. xmlSchemaIDCMatcherPtr next; /* next in the list */
  727. xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  728. xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  729. int idcType;
  730. xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  731. elements */
  732. int sizeKeySeqs;
  733. xmlSchemaItemListPtr targets; /* list of target-node
  734. (xmlSchemaPSVIIDCNodePtr) entries */
  735. };
  736. /*
  737. * Element info flags.
  738. */
  739. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
  740. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  741. #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
  742. #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
  743. #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
  744. #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
  745. #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
  746. #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
  747. #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
  748. #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
  749. #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
  750. /**
  751. * xmlSchemaNodeInfo:
  752. *
  753. * Holds information of an element node.
  754. */
  755. struct _xmlSchemaNodeInfo {
  756. int nodeType;
  757. xmlNodePtr node;
  758. int nodeLine;
  759. const xmlChar *localName;
  760. const xmlChar *nsName;
  761. const xmlChar *value;
  762. xmlSchemaValPtr val; /* the pre-computed value if any */
  763. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  764. int flags; /* combination of node info flags */
  765. int valNeeded;
  766. int normVal;
  767. xmlSchemaElementPtr decl; /* the element/attribute declaration */
  768. int depth;
  769. xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  770. for the scope element*/
  771. xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  772. element */
  773. xmlRegExecCtxtPtr regexCtxt;
  774. const xmlChar **nsBindings; /* Namespace bindings on this element */
  775. int nbNsBindings;
  776. int sizeNsBindings;
  777. int hasKeyrefs;
  778. int appliedXPath; /* Indicates that an XPath has been applied. */
  779. };
  780. #define XML_SCHEMAS_ATTR_UNKNOWN 1
  781. #define XML_SCHEMAS_ATTR_ASSESSED 2
  782. #define XML_SCHEMAS_ATTR_PROHIBITED 3
  783. #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  784. #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  785. #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  786. #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  787. #define XML_SCHEMAS_ATTR_DEFAULT 8
  788. #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  789. #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  790. #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  791. #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  792. #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  793. #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  794. #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  795. #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  796. #define XML_SCHEMAS_ATTR_META 17
  797. /*
  798. * @metaType values of xmlSchemaAttrInfo.
  799. */
  800. #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  801. #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  802. #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  803. #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  804. #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  805. typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  806. typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  807. struct _xmlSchemaAttrInfo {
  808. int nodeType;
  809. xmlNodePtr node;
  810. int nodeLine;
  811. const xmlChar *localName;
  812. const xmlChar *nsName;
  813. const xmlChar *value;
  814. xmlSchemaValPtr val; /* the pre-computed value if any */
  815. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  816. int flags; /* combination of node info flags */
  817. xmlSchemaAttributePtr decl; /* the attribute declaration */
  818. xmlSchemaAttributeUsePtr use; /* the attribute use */
  819. int state;
  820. int metaType;
  821. const xmlChar *vcValue; /* the value constraint value */
  822. xmlSchemaNodeInfoPtr parent;
  823. };
  824. #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  825. /**
  826. * xmlSchemaValidCtxt:
  827. *
  828. * A Schemas validation context
  829. */
  830. struct _xmlSchemaValidCtxt {
  831. int type;
  832. void *errCtxt; /* user specific data block */
  833. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  834. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  835. xmlStructuredErrorFunc serror;
  836. xmlSchemaPtr schema; /* The schema in use */
  837. xmlDocPtr doc;
  838. xmlParserInputBufferPtr input;
  839. xmlCharEncoding enc;
  840. xmlSAXHandlerPtr sax;
  841. xmlParserCtxtPtr parserCtxt;
  842. void *user_data; /* TODO: What is this for? */
  843. int err;
  844. int nberrors;
  845. xmlNodePtr node;
  846. xmlNodePtr cur;
  847. /* xmlSchemaTypePtr type; */
  848. xmlRegExecCtxtPtr regexp;
  849. xmlSchemaValPtr value;
  850. int valueWS;
  851. int options;
  852. xmlNodePtr validationRoot;
  853. xmlSchemaParserCtxtPtr pctxt;
  854. int xsiAssemble;
  855. int depth;
  856. xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
  857. int sizeElemInfos;
  858. xmlSchemaNodeInfoPtr inode; /* the current element information */
  859. xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
  860. xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
  861. xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
  862. xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
  863. xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
  864. int nbIdcNodes;
  865. int sizeIdcNodes;
  866. xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
  867. int nbIdcKeys;
  868. int sizeIdcKeys;
  869. int flags;
  870. xmlDictPtr dict;
  871. #ifdef LIBXML_READER_ENABLED
  872. xmlTextReaderPtr reader;
  873. #endif
  874. xmlSchemaAttrInfoPtr *attrInfos;
  875. int nbAttrInfos;
  876. int sizeAttrInfos;
  877. int skipDepth;
  878. xmlSchemaItemListPtr nodeQNames;
  879. int hasKeyrefs;
  880. int createIDCNodeTables;
  881. int psviExposeIDCNodeTables;
  882. };
  883. /**
  884. * xmlSchemaSubstGroup:
  885. *
  886. *
  887. */
  888. typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
  889. typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
  890. struct _xmlSchemaSubstGroup {
  891. xmlSchemaElementPtr head;
  892. xmlSchemaItemListPtr members;
  893. };
  894. /************************************************************************
  895. * *
  896. * Some predeclarations *
  897. * *
  898. ************************************************************************/
  899. static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
  900. xmlSchemaPtr schema,
  901. xmlNodePtr node);
  902. static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
  903. xmlSchemaPtr schema,
  904. xmlNodePtr node);
  905. static int
  906. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  907. xmlSchemaAbstractCtxtPtr ctxt);
  908. static const xmlChar *
  909. xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
  910. static int
  911. xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  912. xmlNodePtr node);
  913. static int
  914. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  915. xmlSchemaParserCtxtPtr ctxt);
  916. static void
  917. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
  918. static xmlSchemaWhitespaceValueType
  919. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
  920. static xmlSchemaTreeItemPtr
  921. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  922. xmlNodePtr node, xmlSchemaTypeType type,
  923. int withParticle);
  924. static const xmlChar *
  925. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
  926. static xmlSchemaTypeLinkPtr
  927. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
  928. static void
  929. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  930. const char *funcName,
  931. const char *message);
  932. static int
  933. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
  934. xmlSchemaTypePtr type,
  935. xmlSchemaTypePtr baseType,
  936. int subset);
  937. static void
  938. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  939. xmlSchemaParserCtxtPtr ctxt);
  940. static void
  941. xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
  942. static xmlSchemaQNameRefPtr
  943. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  944. xmlSchemaPtr schema,
  945. xmlNodePtr node);
  946. /************************************************************************
  947. * *
  948. * Helper functions *
  949. * *
  950. ************************************************************************/
  951. /**
  952. * xmlSchemaItemTypeToStr:
  953. * @type: the type of the schema item
  954. *
  955. * Returns the component name of a schema item.
  956. */
  957. static const xmlChar *
  958. xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
  959. {
  960. switch (type) {
  961. case XML_SCHEMA_TYPE_BASIC:
  962. return(BAD_CAST "simple type definition");
  963. case XML_SCHEMA_TYPE_SIMPLE:
  964. return(BAD_CAST "simple type definition");
  965. case XML_SCHEMA_TYPE_COMPLEX:
  966. return(BAD_CAST "complex type definition");
  967. case XML_SCHEMA_TYPE_ELEMENT:
  968. return(BAD_CAST "element declaration");
  969. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  970. return(BAD_CAST "attribute use");
  971. case XML_SCHEMA_TYPE_ATTRIBUTE:
  972. return(BAD_CAST "attribute declaration");
  973. case XML_SCHEMA_TYPE_GROUP:
  974. return(BAD_CAST "model group definition");
  975. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  976. return(BAD_CAST "attribute group definition");
  977. case XML_SCHEMA_TYPE_NOTATION:
  978. return(BAD_CAST "notation declaration");
  979. case XML_SCHEMA_TYPE_SEQUENCE:
  980. return(BAD_CAST "model group (sequence)");
  981. case XML_SCHEMA_TYPE_CHOICE:
  982. return(BAD_CAST "model group (choice)");
  983. case XML_SCHEMA_TYPE_ALL:
  984. return(BAD_CAST "model group (all)");
  985. case XML_SCHEMA_TYPE_PARTICLE:
  986. return(BAD_CAST "particle");
  987. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  988. return(BAD_CAST "unique identity-constraint");
  989. /* return(BAD_CAST "IDC (unique)"); */
  990. case XML_SCHEMA_TYPE_IDC_KEY:
  991. return(BAD_CAST "key identity-constraint");
  992. /* return(BAD_CAST "IDC (key)"); */
  993. case XML_SCHEMA_TYPE_IDC_KEYREF:
  994. return(BAD_CAST "keyref identity-constraint");
  995. /* return(BAD_CAST "IDC (keyref)"); */
  996. case XML_SCHEMA_TYPE_ANY:
  997. return(BAD_CAST "wildcard (any)");
  998. case XML_SCHEMA_EXTRA_QNAMEREF:
  999. return(BAD_CAST "[helper component] QName reference");
  1000. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  1001. return(BAD_CAST "[helper component] attribute use prohibition");
  1002. default:
  1003. return(BAD_CAST "Not a schema component");
  1004. }
  1005. }
  1006. /**
  1007. * xmlSchemaGetComponentTypeStr:
  1008. * @type: the type of the schema item
  1009. *
  1010. * Returns the component name of a schema item.
  1011. */
  1012. static const xmlChar *
  1013. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
  1014. {
  1015. switch (item->type) {
  1016. case XML_SCHEMA_TYPE_BASIC:
  1017. if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
  1018. return(BAD_CAST "complex type definition");
  1019. else
  1020. return(BAD_CAST "simple type definition");
  1021. default:
  1022. return(xmlSchemaItemTypeToStr(item->type));
  1023. }
  1024. }
  1025. /**
  1026. * xmlSchemaGetComponentNode:
  1027. * @item: a schema component
  1028. *
  1029. * Returns node associated with the schema component.
  1030. * NOTE that such a node need not be available; plus, a component's
  1031. * node need not to reflect the component directly, since there is no
  1032. * one-to-one relationship between the XML Schema representation and
  1033. * the component representation.
  1034. */
  1035. static xmlNodePtr
  1036. xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
  1037. {
  1038. switch (item->type) {
  1039. case XML_SCHEMA_TYPE_ELEMENT:
  1040. return (((xmlSchemaElementPtr) item)->node);
  1041. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1042. return (((xmlSchemaAttributePtr) item)->node);
  1043. case XML_SCHEMA_TYPE_COMPLEX:
  1044. case XML_SCHEMA_TYPE_SIMPLE:
  1045. return (((xmlSchemaTypePtr) item)->node);
  1046. case XML_SCHEMA_TYPE_ANY:
  1047. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1048. return (((xmlSchemaWildcardPtr) item)->node);
  1049. case XML_SCHEMA_TYPE_PARTICLE:
  1050. return (((xmlSchemaParticlePtr) item)->node);
  1051. case XML_SCHEMA_TYPE_SEQUENCE:
  1052. case XML_SCHEMA_TYPE_CHOICE:
  1053. case XML_SCHEMA_TYPE_ALL:
  1054. return (((xmlSchemaModelGroupPtr) item)->node);
  1055. case XML_SCHEMA_TYPE_GROUP:
  1056. return (((xmlSchemaModelGroupDefPtr) item)->node);
  1057. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1058. return (((xmlSchemaAttributeGroupPtr) item)->node);
  1059. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1060. case XML_SCHEMA_TYPE_IDC_KEY:
  1061. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1062. return (((xmlSchemaIDCPtr) item)->node);
  1063. case XML_SCHEMA_EXTRA_QNAMEREF:
  1064. return(((xmlSchemaQNameRefPtr) item)->node);
  1065. /* TODO: What to do with NOTATIONs?
  1066. case XML_SCHEMA_TYPE_NOTATION:
  1067. return (((xmlSchemaNotationPtr) item)->node);
  1068. */
  1069. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1070. return (((xmlSchemaAttributeUsePtr) item)->node);
  1071. default:
  1072. return (NULL);
  1073. }
  1074. }
  1075. #if 0
  1076. /**
  1077. * xmlSchemaGetNextComponent:
  1078. * @item: a schema component
  1079. *
  1080. * Returns the next sibling of the schema component.
  1081. */
  1082. static xmlSchemaBasicItemPtr
  1083. xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
  1084. {
  1085. switch (item->type) {
  1086. case XML_SCHEMA_TYPE_ELEMENT:
  1087. return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
  1088. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1089. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
  1090. case XML_SCHEMA_TYPE_COMPLEX:
  1091. case XML_SCHEMA_TYPE_SIMPLE:
  1092. return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
  1093. case XML_SCHEMA_TYPE_ANY:
  1094. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1095. return (NULL);
  1096. case XML_SCHEMA_TYPE_PARTICLE:
  1097. return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
  1098. case XML_SCHEMA_TYPE_SEQUENCE:
  1099. case XML_SCHEMA_TYPE_CHOICE:
  1100. case XML_SCHEMA_TYPE_ALL:
  1101. return (NULL);
  1102. case XML_SCHEMA_TYPE_GROUP:
  1103. return (NULL);
  1104. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1105. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
  1106. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1107. case XML_SCHEMA_TYPE_IDC_KEY:
  1108. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1109. return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
  1110. default:
  1111. return (NULL);
  1112. }
  1113. }
  1114. #endif
  1115. /**
  1116. * xmlSchemaFormatQName:
  1117. * @buf: the string buffer
  1118. * @namespaceName: the namespace name
  1119. * @localName: the local name
  1120. *
  1121. * Returns the given QName in the format "{namespaceName}localName" or
  1122. * just "localName" if @namespaceName is NULL.
  1123. *
  1124. * Returns the localName if @namespaceName is NULL, a formatted
  1125. * string otherwise.
  1126. */
  1127. static const xmlChar*
  1128. xmlSchemaFormatQName(xmlChar **buf,
  1129. const xmlChar *namespaceName,
  1130. const xmlChar *localName)
  1131. {
  1132. FREE_AND_NULL(*buf)
  1133. if (namespaceName != NULL) {
  1134. *buf = xmlStrdup(BAD_CAST "{");
  1135. *buf = xmlStrcat(*buf, namespaceName);
  1136. *buf = xmlStrcat(*buf, BAD_CAST "}");
  1137. }
  1138. if (localName != NULL) {
  1139. if (namespaceName == NULL)
  1140. return(localName);
  1141. *buf = xmlStrcat(*buf, localName);
  1142. } else {
  1143. *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
  1144. }
  1145. return ((const xmlChar *) *buf);
  1146. }
  1147. static const xmlChar*
  1148. xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
  1149. {
  1150. if (ns != NULL)
  1151. return (xmlSchemaFormatQName(buf, ns->href, localName));
  1152. else
  1153. return (xmlSchemaFormatQName(buf, NULL, localName));
  1154. }
  1155. static const xmlChar *
  1156. xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
  1157. {
  1158. switch (item->type) {
  1159. case XML_SCHEMA_TYPE_ELEMENT:
  1160. return (((xmlSchemaElementPtr) item)->name);
  1161. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1162. return (((xmlSchemaAttributePtr) item)->name);
  1163. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1164. return (((xmlSchemaAttributeGroupPtr) item)->name);
  1165. case XML_SCHEMA_TYPE_BASIC:
  1166. case XML_SCHEMA_TYPE_SIMPLE:
  1167. case XML_SCHEMA_TYPE_COMPLEX:
  1168. return (((xmlSchemaTypePtr) item)->name);
  1169. case XML_SCHEMA_TYPE_GROUP:
  1170. return (((xmlSchemaModelGroupDefPtr) item)->name);
  1171. case XML_SCHEMA_TYPE_IDC_KEY:
  1172. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1173. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1174. return (((xmlSchemaIDCPtr) item)->name);
  1175. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1176. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1177. return(xmlSchemaGetComponentName(
  1178. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1179. } else
  1180. return(NULL);
  1181. case XML_SCHEMA_EXTRA_QNAMEREF:
  1182. return (((xmlSchemaQNameRefPtr) item)->name);
  1183. case XML_SCHEMA_TYPE_NOTATION:
  1184. return (((xmlSchemaNotationPtr) item)->name);
  1185. default:
  1186. /*
  1187. * Other components cannot have names.
  1188. */
  1189. break;
  1190. }
  1191. return (NULL);
  1192. }
  1193. #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
  1194. #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
  1195. /*
  1196. static const xmlChar *
  1197. xmlSchemaGetQNameRefName(void *ref)
  1198. {
  1199. return(((xmlSchemaQNameRefPtr) ref)->name);
  1200. }
  1201. static const xmlChar *
  1202. xmlSchemaGetQNameRefTargetNs(void *ref)
  1203. {
  1204. return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
  1205. }
  1206. */
  1207. static const xmlChar *
  1208. xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
  1209. {
  1210. switch (item->type) {
  1211. case XML_SCHEMA_TYPE_ELEMENT:
  1212. return (((xmlSchemaElementPtr) item)->targetNamespace);
  1213. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1214. return (((xmlSchemaAttributePtr) item)->targetNamespace);
  1215. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1216. return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
  1217. case XML_SCHEMA_TYPE_BASIC:
  1218. return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
  1219. case XML_SCHEMA_TYPE_SIMPLE:
  1220. case XML_SCHEMA_TYPE_COMPLEX:
  1221. return (((xmlSchemaTypePtr) item)->targetNamespace);
  1222. case XML_SCHEMA_TYPE_GROUP:
  1223. return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
  1224. case XML_SCHEMA_TYPE_IDC_KEY:
  1225. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1226. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1227. return (((xmlSchemaIDCPtr) item)->targetNamespace);
  1228. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1229. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1230. return(xmlSchemaGetComponentTargetNs(
  1231. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1232. }
  1233. /* TODO: Will returning NULL break something? */
  1234. break;
  1235. case XML_SCHEMA_EXTRA_QNAMEREF:
  1236. return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
  1237. case XML_SCHEMA_TYPE_NOTATION:
  1238. return (((xmlSchemaNotationPtr) item)->targetNamespace);
  1239. default:
  1240. /*
  1241. * Other components cannot have names.
  1242. */
  1243. break;
  1244. }
  1245. return (NULL);
  1246. }
  1247. static const xmlChar*
  1248. xmlSchemaGetComponentQName(xmlChar **buf,
  1249. void *item)
  1250. {
  1251. return (xmlSchemaFormatQName(buf,
  1252. xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
  1253. xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
  1254. }
  1255. static const xmlChar*
  1256. xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
  1257. {
  1258. xmlChar *str = NULL;
  1259. *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
  1260. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1261. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
  1262. (xmlSchemaBasicItemPtr) item));
  1263. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1264. FREE_AND_NULL(str);
  1265. return(*buf);
  1266. }
  1267. static const xmlChar*
  1268. xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
  1269. {
  1270. return(xmlSchemaGetComponentDesignation(buf, idc));
  1271. }
  1272. /**
  1273. * xmlSchemaWildcardPCToString:
  1274. * @pc: the type of processContents
  1275. *
  1276. * Returns a string representation of the type of
  1277. * processContents.
  1278. */
  1279. static const xmlChar *
  1280. xmlSchemaWildcardPCToString(int pc)
  1281. {
  1282. switch (pc) {
  1283. case XML_SCHEMAS_ANY_SKIP:
  1284. return (BAD_CAST "skip");
  1285. case XML_SCHEMAS_ANY_LAX:
  1286. return (BAD_CAST "lax");
  1287. case XML_SCHEMAS_ANY_STRICT:
  1288. return (BAD_CAST "strict");
  1289. default:
  1290. return (BAD_CAST "invalid process contents");
  1291. }
  1292. }
  1293. /**
  1294. * xmlSchemaGetCanonValueWhtspExt:
  1295. * @val: the precomputed value
  1296. * @retValue: the returned value
  1297. * @ws: the whitespace type of the value
  1298. *
  1299. * Get a the cononical representation of the value.
  1300. * The caller has to free the returned retValue.
  1301. *
  1302. * Returns 0 if the value could be built and -1 in case of
  1303. * API errors or if the value type is not supported yet.
  1304. */
  1305. static int
  1306. xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
  1307. xmlSchemaWhitespaceValueType ws,
  1308. xmlChar **retValue)
  1309. {
  1310. int list;
  1311. xmlSchemaValType valType;
  1312. const xmlChar *value, *value2 = NULL;
  1313. if ((retValue == NULL) || (val == NULL))
  1314. return (-1);
  1315. list = xmlSchemaValueGetNext(val) ? 1 : 0;
  1316. *retValue = NULL;
  1317. do {
  1318. value = NULL;
  1319. valType = xmlSchemaGetValType(val);
  1320. switch (valType) {
  1321. case XML_SCHEMAS_STRING:
  1322. case XML_SCHEMAS_NORMSTRING:
  1323. case XML_SCHEMAS_ANYSIMPLETYPE:
  1324. value = xmlSchemaValueGetAsString(val);
  1325. if (value != NULL) {
  1326. if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
  1327. value2 = xmlSchemaCollapseString(value);
  1328. else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
  1329. value2 = xmlSchemaWhiteSpaceReplace(value);
  1330. if (value2 != NULL)
  1331. value = value2;
  1332. }
  1333. break;
  1334. default:
  1335. if (xmlSchemaGetCanonValue(val, &value2) == -1) {
  1336. if (value2 != NULL)
  1337. xmlFree((xmlChar *) value2);
  1338. goto internal_error;
  1339. }
  1340. value = value2;
  1341. }
  1342. if (*retValue == NULL)
  1343. if (value == NULL) {
  1344. if (! list)
  1345. *retValue = xmlStrdup(BAD_CAST "");
  1346. } else
  1347. *retValue = xmlStrdup(value);
  1348. else if (value != NULL) {
  1349. /* List. */
  1350. *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
  1351. *retValue = xmlStrcat((xmlChar *) *retValue, value);
  1352. }
  1353. FREE_AND_NULL(value2)
  1354. val = xmlSchemaValueGetNext(val);
  1355. } while (val != NULL);
  1356. return (0);
  1357. internal_error:
  1358. if (*retValue != NULL)
  1359. xmlFree((xmlChar *) (*retValue));
  1360. if (value2 != NULL)
  1361. xmlFree((xmlChar *) value2);
  1362. return (-1);
  1363. }
  1364. /**
  1365. * xmlSchemaFormatItemForReport:
  1366. * @buf: the string buffer
  1367. * @itemDes: the designation of the item
  1368. * @itemName: the name of the item
  1369. * @item: the item as an object
  1370. * @itemNode: the node of the item
  1371. * @local: the local name
  1372. * @parsing: if the function is used during the parse
  1373. *
  1374. * Returns a representation of the given item used
  1375. * for error reports.
  1376. *
  1377. * The following order is used to build the resulting
  1378. * designation if the arguments are not NULL:
  1379. * 1a. If itemDes not NULL -> itemDes
  1380. * 1b. If (itemDes not NULL) and (itemName not NULL)
  1381. * -> itemDes + itemName
  1382. * 2. If the preceding was NULL and (item not NULL) -> item
  1383. * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
  1384. *
  1385. * If the itemNode is an attribute node, the name of the attribute
  1386. * will be appended to the result.
  1387. *
  1388. * Returns the formatted string and sets @buf to the resulting value.
  1389. */
  1390. static xmlChar*
  1391. xmlSchemaFormatItemForReport(xmlChar **buf,
  1392. const xmlChar *itemDes,
  1393. xmlSchemaBasicItemPtr item,
  1394. xmlNodePtr itemNode)
  1395. {
  1396. xmlChar *str = NULL;
  1397. int named = 1;
  1398. if (*buf != NULL) {
  1399. xmlFree(*buf);
  1400. *buf = NULL;
  1401. }
  1402. if (itemDes != NULL) {
  1403. *buf = xmlStrdup(itemDes);
  1404. } else if (item != NULL) {
  1405. switch (item->type) {
  1406. case XML_SCHEMA_TYPE_BASIC: {
  1407. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1408. if (WXS_IS_ATOMIC(type))
  1409. *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
  1410. else if (WXS_IS_LIST(type))
  1411. *buf = xmlStrdup(BAD_CAST "list type 'xs:");
  1412. else if (WXS_IS_UNION(type))
  1413. *buf = xmlStrdup(BAD_CAST "union type 'xs:");
  1414. else
  1415. *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
  1416. *buf = xmlStrcat(*buf, type->name);
  1417. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1418. }
  1419. break;
  1420. case XML_SCHEMA_TYPE_SIMPLE: {
  1421. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1422. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1423. *buf = xmlStrdup(BAD_CAST"");
  1424. } else {
  1425. *buf = xmlStrdup(BAD_CAST "local ");
  1426. }
  1427. if (WXS_IS_ATOMIC(type))
  1428. *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
  1429. else if (WXS_IS_LIST(type))
  1430. *buf = xmlStrcat(*buf, BAD_CAST "list type");
  1431. else if (WXS_IS_UNION(type))
  1432. *buf = xmlStrcat(*buf, BAD_CAST "union type");
  1433. else
  1434. *buf = xmlStrcat(*buf, BAD_CAST "simple type");
  1435. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1436. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1437. *buf = xmlStrcat(*buf, type->name);
  1438. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1439. }
  1440. }
  1441. break;
  1442. case XML_SCHEMA_TYPE_COMPLEX: {
  1443. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1444. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
  1445. *buf = xmlStrdup(BAD_CAST "");
  1446. else
  1447. *buf = xmlStrdup(BAD_CAST "local ");
  1448. *buf = xmlStrcat(*buf, BAD_CAST "complex type");
  1449. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1450. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1451. *buf = xmlStrcat(*buf, type->name);
  1452. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1453. }
  1454. }
  1455. break;
  1456. case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
  1457. xmlSchemaAttributeUsePtr ause;
  1458. ause = WXS_ATTR_USE_CAST item;
  1459. *buf = xmlStrdup(BAD_CAST "attribute use ");
  1460. if (WXS_ATTRUSE_DECL(ause) != NULL) {
  1461. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1462. *buf = xmlStrcat(*buf,
  1463. xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
  1464. FREE_AND_NULL(str)
  1465. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1466. } else {
  1467. *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
  1468. }
  1469. }
  1470. break;
  1471. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  1472. xmlSchemaAttributePtr attr;
  1473. attr = (xmlSchemaAttributePtr) item;
  1474. *buf = xmlStrdup(BAD_CAST "attribute decl.");
  1475. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1476. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1477. attr->targetNamespace, attr->name));
  1478. FREE_AND_NULL(str)
  1479. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1480. }
  1481. break;
  1482. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1483. xmlSchemaGetComponentDesignation(buf, item);
  1484. break;
  1485. case XML_SCHEMA_TYPE_ELEMENT: {
  1486. xmlSchemaElementPtr elem;
  1487. elem = (xmlSchemaElementPtr) item;
  1488. *buf = xmlStrdup(BAD_CAST "element decl.");
  1489. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1490. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1491. elem->targetNamespace, elem->name));
  1492. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1493. }
  1494. break;
  1495. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1496. case XML_SCHEMA_TYPE_IDC_KEY:
  1497. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1498. if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
  1499. *buf = xmlStrdup(BAD_CAST "unique '");
  1500. else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
  1501. *buf = xmlStrdup(BAD_CAST "key '");
  1502. else
  1503. *buf = xmlStrdup(BAD_CAST "keyRef '");
  1504. *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
  1505. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1506. break;
  1507. case XML_SCHEMA_TYPE_ANY:
  1508. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1509. *buf = xmlStrdup(xmlSchemaWildcardPCToString(
  1510. ((xmlSchemaWildcardPtr) item)->processContents));
  1511. *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
  1512. break;
  1513. case XML_SCHEMA_FACET_MININCLUSIVE:
  1514. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  1515. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  1516. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  1517. case XML_SCHEMA_FACET_TOTALDIGITS:
  1518. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  1519. case XML_SCHEMA_FACET_PATTERN:
  1520. case XML_SCHEMA_FACET_ENUMERATION:
  1521. case XML_SCHEMA_FACET_WHITESPACE:
  1522. case XML_SCHEMA_FACET_LENGTH:
  1523. case XML_SCHEMA_FACET_MAXLENGTH:
  1524. case XML_SCHEMA_FACET_MINLENGTH:
  1525. *buf = xmlStrdup(BAD_CAST "facet '");
  1526. *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
  1527. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1528. break;
  1529. case XML_SCHEMA_TYPE_GROUP: {
  1530. *buf = xmlStrdup(BAD_CAST "model group def.");
  1531. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1532. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1533. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1534. FREE_AND_NULL(str)
  1535. }
  1536. break;
  1537. case XML_SCHEMA_TYPE_SEQUENCE:
  1538. case XML_SCHEMA_TYPE_CHOICE:
  1539. case XML_SCHEMA_TYPE_ALL:
  1540. case XML_SCHEMA_TYPE_PARTICLE:
  1541. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1542. break;
  1543. case XML_SCHEMA_TYPE_NOTATION: {
  1544. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1545. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1546. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1547. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1548. FREE_AND_NULL(str);
  1549. }
  1550. default:
  1551. named = 0;
  1552. }
  1553. } else
  1554. named = 0;
  1555. if ((named == 0) && (itemNode != NULL)) {
  1556. xmlNodePtr elem;
  1557. if (itemNode->type == XML_ATTRIBUTE_NODE)
  1558. elem = itemNode->parent;
  1559. else
  1560. elem = itemNode;
  1561. *buf = xmlStrdup(BAD_CAST "Element '");
  1562. if (elem->ns != NULL) {
  1563. *buf = xmlStrcat(*buf,
  1564. xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
  1565. FREE_AND_NULL(str)
  1566. } else
  1567. *buf = xmlStrcat(*buf, elem->name);
  1568. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1569. }
  1570. if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
  1571. *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
  1572. if (itemNode->ns != NULL) {
  1573. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1574. itemNode->ns->href, itemNode->name));
  1575. FREE_AND_NULL(str)
  1576. } else
  1577. *buf = xmlStrcat(*buf, itemNode->name);
  1578. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1579. }
  1580. FREE_AND_NULL(str)
  1581. return (*buf);
  1582. }
  1583. /**
  1584. * xmlSchemaFormatFacetEnumSet:
  1585. * @buf: the string buffer
  1586. * @type: the type holding the enumeration facets
  1587. *
  1588. * Builds a string consisting of all enumeration elements.
  1589. *
  1590. * Returns a string of all enumeration elements.
  1591. */
  1592. static const xmlChar *
  1593. xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
  1594. xmlChar **buf, xmlSchemaTypePtr type)
  1595. {
  1596. xmlSchemaFacetPtr facet;
  1597. xmlSchemaWhitespaceValueType ws;
  1598. xmlChar *value = NULL;
  1599. int res, found = 0;
  1600. if (*buf != NULL)
  1601. xmlFree(*buf);
  1602. *buf = NULL;
  1603. do {
  1604. /*
  1605. * Use the whitespace type of the base type.
  1606. */
  1607. ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
  1608. for (facet = type->facets; facet != NULL; facet = facet->next) {
  1609. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  1610. continue;
  1611. found = 1;
  1612. res = xmlSchemaGetCanonValueWhtspExt(facet->val,
  1613. ws, &value);
  1614. if (res == -1) {
  1615. xmlSchemaInternalErr(actxt,
  1616. "xmlSchemaFormatFacetEnumSet",
  1617. "compute the canonical lexical representation");
  1618. if (*buf != NULL)
  1619. xmlFree(*buf);
  1620. *buf = NULL;
  1621. return (NULL);
  1622. }
  1623. if (*buf == NULL)
  1624. *buf = xmlStrdup(BAD_CAST "'");
  1625. else
  1626. *buf = xmlStrcat(*buf, BAD_CAST ", '");
  1627. *buf = xmlStrcat(*buf, BAD_CAST value);
  1628. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1629. if (value != NULL) {
  1630. xmlFree((xmlChar *)value);
  1631. value = NULL;
  1632. }
  1633. }
  1634. /*
  1635. * The enumeration facet of a type restricts the enumeration
  1636. * facet of the ancestor type; i.e., such restricted enumerations
  1637. * do not belong to the set of the given type. Thus we break
  1638. * on the first found enumeration.
  1639. */
  1640. if (found)
  1641. break;
  1642. type = type->baseType;
  1643. } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
  1644. return ((const xmlChar *) *buf);
  1645. }
  1646. /************************************************************************
  1647. * *
  1648. * Error functions *
  1649. * *
  1650. ************************************************************************/
  1651. #if 0
  1652. static void
  1653. xmlSchemaErrMemory(const char *msg)
  1654. {
  1655. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1656. msg);
  1657. }
  1658. #endif
  1659. static void
  1660. xmlSchemaPSimpleErr(const char *msg)
  1661. {
  1662. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1663. msg);
  1664. }
  1665. /**
  1666. * xmlSchemaPErrMemory:
  1667. * @node: a context node
  1668. * @extra: extra informations
  1669. *
  1670. * Handle an out of memory condition
  1671. */
  1672. static void
  1673. xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
  1674. const char *extra, xmlNodePtr node)
  1675. {
  1676. if (ctxt != NULL)
  1677. ctxt->nberrors++;
  1678. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
  1679. extra);
  1680. }
  1681. /**
  1682. * xmlSchemaPErr:
  1683. * @ctxt: the parsing context
  1684. * @node: the context node
  1685. * @error: the error code
  1686. * @msg: the error message
  1687. * @str1: extra data
  1688. * @str2: extra data
  1689. *
  1690. * Handle a parser error
  1691. */
  1692. static void
  1693. xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1694. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1695. {
  1696. xmlGenericErrorFunc channel = NULL;
  1697. xmlStructuredErrorFunc schannel = NULL;
  1698. void *data = NULL;
  1699. if (ctxt != NULL) {
  1700. ctxt->nberrors++;
  1701. ctxt->err = error;
  1702. channel = ctxt->error;
  1703. data = ctxt->errCtxt;
  1704. schannel = ctxt->serror;
  1705. }
  1706. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1707. error, XML_ERR_ERROR, NULL, 0,
  1708. (const char *) str1, (const char *) str2, NULL, 0, 0,
  1709. msg, str1, str2);
  1710. }
  1711. /**
  1712. * xmlSchemaPErr2:
  1713. * @ctxt: the parsing context
  1714. * @node: the context node
  1715. * @node: the current child
  1716. * @error: the error code
  1717. * @msg: the error message
  1718. * @str1: extra data
  1719. * @str2: extra data
  1720. *
  1721. * Handle a parser error
  1722. */
  1723. static void
  1724. xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  1725. xmlNodePtr child, int error,
  1726. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1727. {
  1728. if (child != NULL)
  1729. xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
  1730. else
  1731. xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
  1732. }
  1733. /**
  1734. * xmlSchemaPErrExt:
  1735. * @ctxt: the parsing context
  1736. * @node: the context node
  1737. * @error: the error code
  1738. * @strData1: extra data
  1739. * @strData2: extra data
  1740. * @strData3: extra data
  1741. * @msg: the message
  1742. * @str1: extra parameter for the message display
  1743. * @str2: extra parameter for the message display
  1744. * @str3: extra parameter for the message display
  1745. * @str4: extra parameter for the message display
  1746. * @str5: extra parameter for the message display
  1747. *
  1748. * Handle a parser error
  1749. */
  1750. static void
  1751. xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1752. const xmlChar * strData1, const xmlChar * strData2,
  1753. const xmlChar * strData3, const char *msg, const xmlChar * str1,
  1754. const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
  1755. const xmlChar * str5)
  1756. {
  1757. xmlGenericErrorFunc channel = NULL;
  1758. xmlStructuredErrorFunc schannel = NULL;
  1759. void *data = NULL;
  1760. if (ctxt != NULL) {
  1761. ctxt->nberrors++;
  1762. ctxt->err = error;
  1763. channel = ctxt->error;
  1764. data = ctxt->errCtxt;
  1765. schannel = ctxt->serror;
  1766. }
  1767. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1768. error, XML_ERR_ERROR, NULL, 0,
  1769. (const char *) strData1, (const char *) strData2,
  1770. (const char *) strData3, 0, 0, msg, str1, str2,
  1771. str3, str4, str5);
  1772. }
  1773. /************************************************************************
  1774. * *
  1775. * Allround error functions *
  1776. * *
  1777. ************************************************************************/
  1778. /**
  1779. * xmlSchemaVTypeErrMemory:
  1780. * @node: a context node
  1781. * @extra: extra informations
  1782. *
  1783. * Handle an out of memory condition
  1784. */
  1785. static void
  1786. xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
  1787. const char *extra, xmlNodePtr node)
  1788. {
  1789. if (ctxt != NULL) {
  1790. ctxt->nberrors++;
  1791. ctxt->err = XML_SCHEMAV_INTERNAL;
  1792. }
  1793. __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
  1794. extra);
  1795. }
  1796. static void
  1797. xmlSchemaPSimpleInternalErr(xmlNodePtr node,
  1798. const char *msg, const xmlChar *str)
  1799. {
  1800. __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
  1801. msg, (const char *) str);
  1802. }
  1803. #define WXS_ERROR_TYPE_ERROR 1
  1804. #define WXS_ERROR_TYPE_WARNING 2
  1805. /**
  1806. * xmlSchemaErr3:
  1807. * @ctxt: the validation context
  1808. * @node: the context node
  1809. * @error: the error code
  1810. * @msg: the error message
  1811. * @str1: extra data
  1812. * @str2: extra data
  1813. * @str3: extra data
  1814. *
  1815. * Handle a validation error
  1816. */
  1817. static void
  1818. xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
  1819. xmlErrorLevel errorLevel,
  1820. int error, xmlNodePtr node, int line, const char *msg,
  1821. const xmlChar *str1, const xmlChar *str2,
  1822. const xmlChar *str3, const xmlChar *str4)
  1823. {
  1824. xmlStructuredErrorFunc schannel = NULL;
  1825. xmlGenericErrorFunc channel = NULL;
  1826. void *data = NULL;
  1827. if (ctxt != NULL) {
  1828. if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1829. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
  1830. const char *file = NULL;
  1831. if (errorLevel != XML_ERR_WARNING) {
  1832. vctxt->nberrors++;
  1833. vctxt->err = error;
  1834. channel = vctxt->error;
  1835. } else {
  1836. channel = vctxt->warning;
  1837. }
  1838. schannel = vctxt->serror;
  1839. data = vctxt->errCtxt;
  1840. /*
  1841. * Error node. If we specify a line number, then
  1842. * do not channel any node to the error function.
  1843. */
  1844. if (line == 0) {
  1845. if ((node == NULL) &&
  1846. (vctxt->depth >= 0) &&
  1847. (vctxt->inode != NULL)) {
  1848. node = vctxt->inode->node;
  1849. }
  1850. /*
  1851. * Get filename and line if no node-tree.
  1852. */
  1853. if ((node == NULL) &&
  1854. (vctxt->parserCtxt != NULL) &&
  1855. (vctxt->parserCtxt->input != NULL)) {
  1856. file = vctxt->parserCtxt->input->filename;
  1857. line = vctxt->parserCtxt->input->line;
  1858. }
  1859. } else {
  1860. /*
  1861. * Override the given node's (if any) position
  1862. * and channel only the given line number.
  1863. */
  1864. node = NULL;
  1865. /*
  1866. * Get filename.
  1867. */
  1868. if (vctxt->doc != NULL)
  1869. file = (const char *) vctxt->doc->URL;
  1870. else if ((vctxt->parserCtxt != NULL) &&
  1871. (vctxt->parserCtxt->input != NULL))
  1872. file = vctxt->parserCtxt->input->filename;
  1873. }
  1874. __xmlRaiseError(schannel, channel, data, ctxt,
  1875. node, XML_FROM_SCHEMASV,
  1876. error, errorLevel, file, line,
  1877. (const char *) str1, (const char *) str2,
  1878. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1879. } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
  1880. xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
  1881. if (errorLevel != XML_ERR_WARNING) {
  1882. pctxt->nberrors++;
  1883. pctxt->err = error;
  1884. channel = pctxt->error;
  1885. } else {
  1886. channel = pctxt->warning;
  1887. }
  1888. schannel = pctxt->serror;
  1889. data = pctxt->errCtxt;
  1890. __xmlRaiseError(schannel, channel, data, ctxt,
  1891. node, XML_FROM_SCHEMASP, error,
  1892. errorLevel, NULL, 0,
  1893. (const char *) str1, (const char *) str2,
  1894. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1895. } else {
  1896. TODO
  1897. }
  1898. }
  1899. }
  1900. /**
  1901. * xmlSchemaErr3:
  1902. * @ctxt: the validation context
  1903. * @node: the context node
  1904. * @error: the error code
  1905. * @msg: the error message
  1906. * @str1: extra data
  1907. * @str2: extra data
  1908. * @str3: extra data
  1909. *
  1910. * Handle a validation error
  1911. */
  1912. static void
  1913. xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
  1914. int error, xmlNodePtr node, const char *msg,
  1915. const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
  1916. {
  1917. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1918. msg, str1, str2, str3, NULL);
  1919. }
  1920. static void
  1921. xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
  1922. int error, xmlNodePtr node, const char *msg,
  1923. const xmlChar *str1, const xmlChar *str2,
  1924. const xmlChar *str3, const xmlChar *str4)
  1925. {
  1926. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1927. msg, str1, str2, str3, str4);
  1928. }
  1929. static void
  1930. xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
  1931. int error, xmlNodePtr node, const char *msg,
  1932. const xmlChar *str1, const xmlChar *str2)
  1933. {
  1934. xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
  1935. }
  1936. static xmlChar *
  1937. xmlSchemaFormatNodeForError(xmlChar ** msg,
  1938. xmlSchemaAbstractCtxtPtr actxt,
  1939. xmlNodePtr node)
  1940. {
  1941. xmlChar *str = NULL;
  1942. *msg = NULL;
  1943. if ((node != NULL) &&
  1944. (node->type != XML_ELEMENT_NODE) &&
  1945. (node->type != XML_ATTRIBUTE_NODE))
  1946. {
  1947. /*
  1948. * Don't try to format other nodes than element and
  1949. * attribute nodes.
  1950. * Play save and return an empty string.
  1951. */
  1952. *msg = xmlStrdup(BAD_CAST "");
  1953. return(*msg);
  1954. }
  1955. if (node != NULL) {
  1956. /*
  1957. * Work on tree nodes.
  1958. */
  1959. if (node->type == XML_ATTRIBUTE_NODE) {
  1960. xmlNodePtr elem = node->parent;
  1961. *msg = xmlStrdup(BAD_CAST "Element '");
  1962. if (elem->ns != NULL)
  1963. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1964. elem->ns->href, elem->name));
  1965. else
  1966. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1967. NULL, elem->name));
  1968. FREE_AND_NULL(str);
  1969. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  1970. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  1971. } else {
  1972. *msg = xmlStrdup(BAD_CAST "Element '");
  1973. }
  1974. if (node->ns != NULL)
  1975. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1976. node->ns->href, node->name));
  1977. else
  1978. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1979. NULL, node->name));
  1980. FREE_AND_NULL(str);
  1981. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  1982. } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1983. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
  1984. /*
  1985. * Work on node infos.
  1986. */
  1987. if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
  1988. xmlSchemaNodeInfoPtr ielem =
  1989. vctxt->elemInfos[vctxt->depth];
  1990. *msg = xmlStrdup(BAD_CAST "Element '");
  1991. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1992. ielem->nsName, ielem->localName));
  1993. FREE_AND_NULL(str);
  1994. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  1995. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  1996. } else {
  1997. *msg = xmlStrdup(BAD_CAST "Element '");
  1998. }
  1999. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2000. vctxt->inode->nsName, vctxt->inode->localName));
  2001. FREE_AND_NULL(str);
  2002. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2003. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  2004. /*
  2005. * Hmm, no node while parsing?
  2006. * Return an empty string, in case NULL will break something.
  2007. */
  2008. *msg = xmlStrdup(BAD_CAST "");
  2009. } else {
  2010. TODO
  2011. return (NULL);
  2012. }
  2013. /*
  2014. * VAL TODO: The output of the given schema component is currently
  2015. * disabled.
  2016. */
  2017. #if 0
  2018. if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
  2019. *msg = xmlStrcat(*msg, BAD_CAST " [");
  2020. *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
  2021. NULL, type, NULL, 0));
  2022. FREE_AND_NULL(str)
  2023. *msg = xmlStrcat(*msg, BAD_CAST "]");
  2024. }
  2025. #endif
  2026. return (*msg);
  2027. }
  2028. static void
  2029. xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
  2030. const char *funcName,
  2031. const char *message,
  2032. const xmlChar *str1,
  2033. const xmlChar *str2)
  2034. {
  2035. xmlChar *msg = NULL;
  2036. if (actxt == NULL)
  2037. return;
  2038. msg = xmlStrdup(BAD_CAST "Internal error: ");
  2039. msg = xmlStrcat(msg, BAD_CAST funcName);
  2040. msg = xmlStrcat(msg, BAD_CAST ", ");
  2041. msg = xmlStrcat(msg, BAD_CAST message);
  2042. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2043. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
  2044. xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
  2045. (const char *) msg, str1, str2);
  2046. else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
  2047. xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
  2048. (const char *) msg, str1, str2);
  2049. FREE_AND_NULL(msg)
  2050. }
  2051. static void
  2052. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  2053. const char *funcName,
  2054. const char *message)
  2055. {
  2056. xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
  2057. }
  2058. #if 0
  2059. static void
  2060. xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
  2061. const char *funcName,
  2062. const char *message,
  2063. const xmlChar *str1,
  2064. const xmlChar *str2)
  2065. {
  2066. xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
  2067. str1, str2);
  2068. }
  2069. #endif
  2070. static void
  2071. xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
  2072. xmlParserErrors error,
  2073. xmlNodePtr node,
  2074. xmlSchemaBasicItemPtr item,
  2075. const char *message,
  2076. const xmlChar *str1, const xmlChar *str2,
  2077. const xmlChar *str3, const xmlChar *str4)
  2078. {
  2079. xmlChar *msg = NULL;
  2080. if ((node == NULL) && (item != NULL) &&
  2081. (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
  2082. node = WXS_ITEM_NODE(item);
  2083. xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
  2084. msg = xmlStrcat(msg, BAD_CAST ": ");
  2085. } else
  2086. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2087. msg = xmlStrcat(msg, (const xmlChar *) message);
  2088. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2089. xmlSchemaErr4(actxt, error, node,
  2090. (const char *) msg, str1, str2, str3, str4);
  2091. FREE_AND_NULL(msg)
  2092. }
  2093. static void
  2094. xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
  2095. xmlParserErrors error,
  2096. xmlNodePtr node,
  2097. xmlSchemaBasicItemPtr item,
  2098. const char *message,
  2099. const xmlChar *str1,
  2100. const xmlChar *str2)
  2101. {
  2102. xmlSchemaCustomErr4(actxt, error, node, item,
  2103. message, str1, str2, NULL, NULL);
  2104. }
  2105. static void
  2106. xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
  2107. xmlParserErrors error,
  2108. xmlNodePtr node,
  2109. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2110. const char *message,
  2111. const xmlChar *str1,
  2112. const xmlChar *str2,
  2113. const xmlChar *str3)
  2114. {
  2115. xmlChar *msg = NULL;
  2116. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2117. msg = xmlStrcat(msg, (const xmlChar *) message);
  2118. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2119. /* URGENT TODO: Set the error code to something sane. */
  2120. xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
  2121. (const char *) msg, str1, str2, str3, NULL);
  2122. FREE_AND_NULL(msg)
  2123. }
  2124. static void
  2125. xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
  2126. xmlParserErrors error,
  2127. xmlSchemaPSVIIDCNodePtr idcNode,
  2128. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2129. const char *message,
  2130. const xmlChar *str1,
  2131. const xmlChar *str2)
  2132. {
  2133. xmlChar *msg = NULL, *qname = NULL;
  2134. msg = xmlStrdup(BAD_CAST "Element '%s': ");
  2135. msg = xmlStrcat(msg, (const xmlChar *) message);
  2136. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2137. xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
  2138. error, NULL, idcNode->nodeLine, (const char *) msg,
  2139. xmlSchemaFormatQName(&qname,
  2140. vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
  2141. vctxt->nodeQNames->items[idcNode->nodeQNameID]),
  2142. str1, str2, NULL);
  2143. FREE_AND_NULL(qname);
  2144. FREE_AND_NULL(msg);
  2145. }
  2146. static int
  2147. xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
  2148. xmlNodePtr node)
  2149. {
  2150. if (node != NULL)
  2151. return (node->type);
  2152. if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
  2153. (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
  2154. return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
  2155. return (-1);
  2156. }
  2157. static int
  2158. xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
  2159. {
  2160. switch (item->type) {
  2161. case XML_SCHEMA_TYPE_COMPLEX:
  2162. case XML_SCHEMA_TYPE_SIMPLE:
  2163. if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
  2164. return(1);
  2165. break;
  2166. case XML_SCHEMA_TYPE_GROUP:
  2167. return (1);
  2168. case XML_SCHEMA_TYPE_ELEMENT:
  2169. if ( ((xmlSchemaElementPtr) item)->flags &
  2170. XML_SCHEMAS_ELEM_GLOBAL)
  2171. return(1);
  2172. break;
  2173. case XML_SCHEMA_TYPE_ATTRIBUTE:
  2174. if ( ((xmlSchemaAttributePtr) item)->flags &
  2175. XML_SCHEMAS_ATTR_GLOBAL)
  2176. return(1);
  2177. break;
  2178. /* Note that attribute groups are always global. */
  2179. default:
  2180. return(1);
  2181. }
  2182. return (0);
  2183. }
  2184. static void
  2185. xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2186. xmlParserErrors error,
  2187. xmlNodePtr node,
  2188. const xmlChar *value,
  2189. xmlSchemaTypePtr type,
  2190. int displayValue)
  2191. {
  2192. xmlChar *msg = NULL;
  2193. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2194. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2195. XML_ATTRIBUTE_NODE))
  2196. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2197. else
  2198. msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
  2199. "value of ");
  2200. if (! xmlSchemaIsGlobalItem(type))
  2201. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2202. else
  2203. msg = xmlStrcat(msg, BAD_CAST "the ");
  2204. if (WXS_IS_ATOMIC(type))
  2205. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2206. else if (WXS_IS_LIST(type))
  2207. msg = xmlStrcat(msg, BAD_CAST "list type");
  2208. else if (WXS_IS_UNION(type))
  2209. msg = xmlStrcat(msg, BAD_CAST "union type");
  2210. if (xmlSchemaIsGlobalItem(type)) {
  2211. xmlChar *str = NULL;
  2212. msg = xmlStrcat(msg, BAD_CAST " '");
  2213. if (type->builtInType != 0) {
  2214. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2215. msg = xmlStrcat(msg, type->name);
  2216. } else
  2217. msg = xmlStrcat(msg,
  2218. xmlSchemaFormatQName(&str,
  2219. type->targetNamespace, type->name));
  2220. msg = xmlStrcat(msg, BAD_CAST "'");
  2221. FREE_AND_NULL(str);
  2222. }
  2223. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2224. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2225. XML_ATTRIBUTE_NODE))
  2226. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2227. else
  2228. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2229. FREE_AND_NULL(msg)
  2230. }
  2231. static const xmlChar *
  2232. xmlSchemaFormatErrorNodeQName(xmlChar ** str,
  2233. xmlSchemaNodeInfoPtr ni,
  2234. xmlNodePtr node)
  2235. {
  2236. if (node != NULL) {
  2237. if (node->ns != NULL)
  2238. return (xmlSchemaFormatQName(str, node->ns->href, node->name));
  2239. else
  2240. return (xmlSchemaFormatQName(str, NULL, node->name));
  2241. } else if (ni != NULL)
  2242. return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
  2243. return (NULL);
  2244. }
  2245. static void
  2246. xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
  2247. xmlParserErrors error,
  2248. xmlSchemaAttrInfoPtr ni,
  2249. xmlNodePtr node)
  2250. {
  2251. xmlChar *msg = NULL, *str = NULL;
  2252. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2253. msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
  2254. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2255. xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
  2256. NULL);
  2257. FREE_AND_NULL(str)
  2258. FREE_AND_NULL(msg)
  2259. }
  2260. static void
  2261. xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2262. xmlParserErrors error,
  2263. xmlNodePtr node,
  2264. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2265. const char *message,
  2266. int nbval,
  2267. int nbneg,
  2268. xmlChar **values)
  2269. {
  2270. xmlChar *str = NULL, *msg = NULL;
  2271. xmlChar *localName, *nsName;
  2272. const xmlChar *cur, *end;
  2273. int i;
  2274. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2275. msg = xmlStrcat(msg, (const xmlChar *) message);
  2276. msg = xmlStrcat(msg, BAD_CAST ".");
  2277. /*
  2278. * Note that is does not make sense to report that we have a
  2279. * wildcard here, since the wildcard might be unfolded into
  2280. * multiple transitions.
  2281. */
  2282. if (nbval + nbneg > 0) {
  2283. if (nbval + nbneg > 1) {
  2284. str = xmlStrdup(BAD_CAST " Expected is one of ( ");
  2285. } else
  2286. str = xmlStrdup(BAD_CAST " Expected is ( ");
  2287. nsName = NULL;
  2288. for (i = 0; i < nbval + nbneg; i++) {
  2289. cur = values[i];
  2290. if (cur == NULL)
  2291. continue;
  2292. if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
  2293. (cur[3] == ' ')) {
  2294. cur += 4;
  2295. str = xmlStrcat(str, BAD_CAST "##other");
  2296. }
  2297. /*
  2298. * Get the local name.
  2299. */
  2300. localName = NULL;
  2301. end = cur;
  2302. if (*end == '*') {
  2303. localName = xmlStrdup(BAD_CAST "*");
  2304. end++;
  2305. } else {
  2306. while ((*end != 0) && (*end != '|'))
  2307. end++;
  2308. localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
  2309. }
  2310. if (*end != 0) {
  2311. end++;
  2312. /*
  2313. * Skip "*|*" if they come with negated expressions, since
  2314. * they represent the same negated wildcard.
  2315. */
  2316. if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
  2317. /*
  2318. * Get the namespace name.
  2319. */
  2320. cur = end;
  2321. if (*end == '*') {
  2322. nsName = xmlStrdup(BAD_CAST "{*}");
  2323. } else {
  2324. while (*end != 0)
  2325. end++;
  2326. if (i >= nbval)
  2327. nsName = xmlStrdup(BAD_CAST "{##other:");
  2328. else
  2329. nsName = xmlStrdup(BAD_CAST "{");
  2330. nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
  2331. nsName = xmlStrcat(nsName, BAD_CAST "}");
  2332. }
  2333. str = xmlStrcat(str, BAD_CAST nsName);
  2334. FREE_AND_NULL(nsName)
  2335. } else {
  2336. FREE_AND_NULL(localName);
  2337. continue;
  2338. }
  2339. }
  2340. str = xmlStrcat(str, BAD_CAST localName);
  2341. FREE_AND_NULL(localName);
  2342. if (i < nbval + nbneg -1)
  2343. str = xmlStrcat(str, BAD_CAST ", ");
  2344. }
  2345. str = xmlStrcat(str, BAD_CAST " ).\n");
  2346. msg = xmlStrcat(msg, BAD_CAST str);
  2347. FREE_AND_NULL(str)
  2348. } else
  2349. msg = xmlStrcat(msg, BAD_CAST "\n");
  2350. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2351. xmlFree(msg);
  2352. }
  2353. static void
  2354. xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
  2355. xmlParserErrors error,
  2356. xmlNodePtr node,
  2357. const xmlChar *value,
  2358. unsigned long length,
  2359. xmlSchemaTypePtr type,
  2360. xmlSchemaFacetPtr facet,
  2361. const char *message,
  2362. const xmlChar *str1,
  2363. const xmlChar *str2)
  2364. {
  2365. xmlChar *str = NULL, *msg = NULL;
  2366. xmlSchemaTypeType facetType;
  2367. int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
  2368. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2369. if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
  2370. facetType = XML_SCHEMA_FACET_ENUMERATION;
  2371. /*
  2372. * If enumerations are validated, one must not expect the
  2373. * facet to be given.
  2374. */
  2375. } else
  2376. facetType = facet->type;
  2377. msg = xmlStrcat(msg, BAD_CAST "[");
  2378. msg = xmlStrcat(msg, BAD_CAST "facet '");
  2379. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
  2380. msg = xmlStrcat(msg, BAD_CAST "'] ");
  2381. if (message == NULL) {
  2382. /*
  2383. * Use a default message.
  2384. */
  2385. if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
  2386. (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
  2387. (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
  2388. char len[25], actLen[25];
  2389. /* FIXME, TODO: What is the max expected string length of the
  2390. * this value?
  2391. */
  2392. if (nodeType == XML_ATTRIBUTE_NODE)
  2393. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
  2394. else
  2395. msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
  2396. snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
  2397. snprintf(actLen, 24, "%lu", length);
  2398. if (facetType == XML_SCHEMA_FACET_LENGTH)
  2399. msg = xmlStrcat(msg,
  2400. BAD_CAST "this differs from the allowed length of '%s'.\n");
  2401. else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
  2402. msg = xmlStrcat(msg,
  2403. BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
  2404. else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
  2405. msg = xmlStrcat(msg,
  2406. BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
  2407. if (nodeType == XML_ATTRIBUTE_NODE)
  2408. xmlSchemaErr3(actxt, error, node, (const char *) msg,
  2409. value, (const xmlChar *) actLen, (const xmlChar *) len);
  2410. else
  2411. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2412. (const xmlChar *) actLen, (const xmlChar *) len);
  2413. } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
  2414. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
  2415. "of the set {%s}.\n");
  2416. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2417. xmlSchemaFormatFacetEnumSet(actxt, &str, type));
  2418. } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
  2419. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
  2420. "by the pattern '%s'.\n");
  2421. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2422. facet->value);
  2423. } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
  2424. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
  2425. "minimum value allowed ('%s').\n");
  2426. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2427. facet->value);
  2428. } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
  2429. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
  2430. "maximum value allowed ('%s').\n");
  2431. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2432. facet->value);
  2433. } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
  2434. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
  2435. "'%s'.\n");
  2436. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2437. facet->value);
  2438. } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
  2439. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
  2440. "'%s'.\n");
  2441. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2442. facet->value);
  2443. } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
  2444. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
  2445. "digits than are allowed ('%s').\n");
  2446. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2447. facet->value);
  2448. } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
  2449. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
  2450. "digits than are allowed ('%s').\n");
  2451. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2452. facet->value);
  2453. } else if (nodeType == XML_ATTRIBUTE_NODE) {
  2454. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
  2455. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2456. } else {
  2457. msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
  2458. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2459. }
  2460. } else {
  2461. msg = xmlStrcat(msg, (const xmlChar *) message);
  2462. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2463. xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
  2464. }
  2465. FREE_AND_NULL(str)
  2466. xmlFree(msg);
  2467. }
  2468. #define VERROR(err, type, msg) \
  2469. xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
  2470. #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
  2471. #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
  2472. #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
  2473. #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
  2474. /**
  2475. * xmlSchemaPMissingAttrErr:
  2476. * @ctxt: the schema validation context
  2477. * @ownerDes: the designation of the owner
  2478. * @ownerName: the name of the owner
  2479. * @ownerItem: the owner as a schema object
  2480. * @ownerElem: the owner as an element node
  2481. * @node: the parent element node of the missing attribute node
  2482. * @type: the corresponding type of the attribute node
  2483. *
  2484. * Reports an illegal attribute.
  2485. */
  2486. static void
  2487. xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2488. xmlParserErrors error,
  2489. xmlSchemaBasicItemPtr ownerItem,
  2490. xmlNodePtr ownerElem,
  2491. const char *name,
  2492. const char *message)
  2493. {
  2494. xmlChar *des = NULL;
  2495. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2496. if (message != NULL)
  2497. xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
  2498. else
  2499. xmlSchemaPErr(ctxt, ownerElem, error,
  2500. "%s: The attribute '%s' is required but missing.\n",
  2501. BAD_CAST des, BAD_CAST name);
  2502. FREE_AND_NULL(des);
  2503. }
  2504. /**
  2505. * xmlSchemaPResCompAttrErr:
  2506. * @ctxt: the schema validation context
  2507. * @error: the error code
  2508. * @ownerDes: the designation of the owner
  2509. * @ownerItem: the owner as a schema object
  2510. * @ownerElem: the owner as an element node
  2511. * @name: the name of the attribute holding the QName
  2512. * @refName: the referenced local name
  2513. * @refURI: the referenced namespace URI
  2514. * @message: optional message
  2515. *
  2516. * Used to report QName attribute values that failed to resolve
  2517. * to schema components.
  2518. */
  2519. static void
  2520. xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2521. xmlParserErrors error,
  2522. xmlSchemaBasicItemPtr ownerItem,
  2523. xmlNodePtr ownerElem,
  2524. const char *name,
  2525. const xmlChar *refName,
  2526. const xmlChar *refURI,
  2527. xmlSchemaTypeType refType,
  2528. const char *refTypeStr)
  2529. {
  2530. xmlChar *des = NULL, *strA = NULL;
  2531. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2532. if (refTypeStr == NULL)
  2533. refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
  2534. xmlSchemaPErrExt(ctxt, ownerElem, error,
  2535. NULL, NULL, NULL,
  2536. "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
  2537. "%s.\n", BAD_CAST des, BAD_CAST name,
  2538. xmlSchemaFormatQName(&strA, refURI, refName),
  2539. BAD_CAST refTypeStr, NULL);
  2540. FREE_AND_NULL(des)
  2541. FREE_AND_NULL(strA)
  2542. }
  2543. /**
  2544. * xmlSchemaPCustomAttrErr:
  2545. * @ctxt: the schema parser context
  2546. * @error: the error code
  2547. * @ownerDes: the designation of the owner
  2548. * @ownerItem: the owner as a schema object
  2549. * @attr: the illegal attribute node
  2550. *
  2551. * Reports an illegal attribute during the parse.
  2552. */
  2553. static void
  2554. xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2555. xmlParserErrors error,
  2556. xmlChar **ownerDes,
  2557. xmlSchemaBasicItemPtr ownerItem,
  2558. xmlAttrPtr attr,
  2559. const char *msg)
  2560. {
  2561. xmlChar *des = NULL;
  2562. if (ownerDes == NULL)
  2563. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
  2564. else if (*ownerDes == NULL) {
  2565. xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
  2566. des = *ownerDes;
  2567. } else
  2568. des = *ownerDes;
  2569. if (attr == NULL) {
  2570. xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
  2571. "%s, attribute '%s': %s.\n",
  2572. BAD_CAST des, (const xmlChar *) "Unknown",
  2573. (const xmlChar *) msg, NULL, NULL);
  2574. } else {
  2575. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2576. "%s, attribute '%s': %s.\n",
  2577. BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
  2578. }
  2579. if (ownerDes == NULL)
  2580. FREE_AND_NULL(des);
  2581. }
  2582. /**
  2583. * xmlSchemaPIllegalAttrErr:
  2584. * @ctxt: the schema parser context
  2585. * @error: the error code
  2586. * @ownerDes: the designation of the attribute's owner
  2587. * @ownerItem: the attribute's owner item
  2588. * @attr: the illegal attribute node
  2589. *
  2590. * Reports an illegal attribute during the parse.
  2591. */
  2592. static void
  2593. xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2594. xmlParserErrors error,
  2595. xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
  2596. xmlAttrPtr attr)
  2597. {
  2598. xmlChar *strA = NULL, *strB = NULL;
  2599. xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
  2600. xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
  2601. "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
  2602. xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
  2603. NULL, NULL);
  2604. FREE_AND_NULL(strA);
  2605. FREE_AND_NULL(strB);
  2606. }
  2607. /**
  2608. * xmlSchemaPCustomErr:
  2609. * @ctxt: the schema parser context
  2610. * @error: the error code
  2611. * @itemDes: the designation of the schema item
  2612. * @item: the schema item
  2613. * @itemElem: the node of the schema item
  2614. * @message: the error message
  2615. * @str1: an optional param for the error message
  2616. * @str2: an optional param for the error message
  2617. * @str3: an optional param for the error message
  2618. *
  2619. * Reports an error during parsing.
  2620. */
  2621. static void
  2622. xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
  2623. xmlParserErrors error,
  2624. xmlSchemaBasicItemPtr item,
  2625. xmlNodePtr itemElem,
  2626. const char *message,
  2627. const xmlChar *str1,
  2628. const xmlChar *str2,
  2629. const xmlChar *str3)
  2630. {
  2631. xmlChar *des = NULL, *msg = NULL;
  2632. xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
  2633. msg = xmlStrdup(BAD_CAST "%s: ");
  2634. msg = xmlStrcat(msg, (const xmlChar *) message);
  2635. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2636. if ((itemElem == NULL) && (item != NULL))
  2637. itemElem = WXS_ITEM_NODE(item);
  2638. xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
  2639. (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
  2640. FREE_AND_NULL(des);
  2641. FREE_AND_NULL(msg);
  2642. }
  2643. /**
  2644. * xmlSchemaPCustomErr:
  2645. * @ctxt: the schema parser context
  2646. * @error: the error code
  2647. * @itemDes: the designation of the schema item
  2648. * @item: the schema item
  2649. * @itemElem: the node of the schema item
  2650. * @message: the error message
  2651. * @str1: the optional param for the error message
  2652. *
  2653. * Reports an error during parsing.
  2654. */
  2655. static void
  2656. xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
  2657. xmlParserErrors error,
  2658. xmlSchemaBasicItemPtr item,
  2659. xmlNodePtr itemElem,
  2660. const char *message,
  2661. const xmlChar *str1)
  2662. {
  2663. xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
  2664. str1, NULL, NULL);
  2665. }
  2666. /**
  2667. * xmlSchemaPAttrUseErr:
  2668. * @ctxt: the schema parser context
  2669. * @error: the error code
  2670. * @itemDes: the designation of the schema type
  2671. * @item: the schema type
  2672. * @itemElem: the node of the schema type
  2673. * @attr: the invalid schema attribute
  2674. * @message: the error message
  2675. * @str1: the optional param for the error message
  2676. *
  2677. * Reports an attribute use error during parsing.
  2678. */
  2679. static void
  2680. xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
  2681. xmlParserErrors error,
  2682. xmlNodePtr node,
  2683. xmlSchemaBasicItemPtr ownerItem,
  2684. const xmlSchemaAttributeUsePtr attruse,
  2685. const char *message,
  2686. const xmlChar *str1, const xmlChar *str2,
  2687. const xmlChar *str3,const xmlChar *str4)
  2688. {
  2689. xmlChar *str = NULL, *msg = NULL;
  2690. xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
  2691. msg = xmlStrcat(msg, BAD_CAST ", ");
  2692. msg = xmlStrcat(msg,
  2693. BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
  2694. WXS_BASIC_CAST attruse, NULL));
  2695. FREE_AND_NULL(str);
  2696. msg = xmlStrcat(msg, BAD_CAST ": ");
  2697. msg = xmlStrcat(msg, (const xmlChar *) message);
  2698. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2699. xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
  2700. (const char *) msg, str1, str2, str3, str4);
  2701. xmlFree(msg);
  2702. }
  2703. /**
  2704. * xmlSchemaPIllegalFacetAtomicErr:
  2705. * @ctxt: the schema parser context
  2706. * @error: the error code
  2707. * @type: the schema type
  2708. * @baseType: the base type of type
  2709. * @facet: the illegal facet
  2710. *
  2711. * Reports an illegal facet for atomic simple types.
  2712. */
  2713. static void
  2714. xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
  2715. xmlParserErrors error,
  2716. xmlSchemaTypePtr type,
  2717. xmlSchemaTypePtr baseType,
  2718. xmlSchemaFacetPtr facet)
  2719. {
  2720. xmlChar *des = NULL, *strT = NULL;
  2721. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
  2722. xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
  2723. "%s: The facet '%s' is not allowed on types derived from the "
  2724. "type %s.\n",
  2725. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
  2726. xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
  2727. NULL, NULL);
  2728. FREE_AND_NULL(des);
  2729. FREE_AND_NULL(strT);
  2730. }
  2731. /**
  2732. * xmlSchemaPIllegalFacetListUnionErr:
  2733. * @ctxt: the schema parser context
  2734. * @error: the error code
  2735. * @itemDes: the designation of the schema item involved
  2736. * @item: the schema item involved
  2737. * @facet: the illegal facet
  2738. *
  2739. * Reports an illegal facet for <list> and <union>.
  2740. */
  2741. static void
  2742. xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
  2743. xmlParserErrors error,
  2744. xmlSchemaTypePtr type,
  2745. xmlSchemaFacetPtr facet)
  2746. {
  2747. xmlChar *des = NULL;
  2748. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
  2749. type->node);
  2750. xmlSchemaPErr(ctxt, type->node, error,
  2751. "%s: The facet '%s' is not allowed.\n",
  2752. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
  2753. FREE_AND_NULL(des);
  2754. }
  2755. /**
  2756. * xmlSchemaPMutualExclAttrErr:
  2757. * @ctxt: the schema validation context
  2758. * @error: the error code
  2759. * @elemDes: the designation of the parent element node
  2760. * @attr: the bad attribute node
  2761. * @type: the corresponding type of the attribute node
  2762. *
  2763. * Reports an illegal attribute.
  2764. */
  2765. static void
  2766. xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2767. xmlParserErrors error,
  2768. xmlSchemaBasicItemPtr ownerItem,
  2769. xmlAttrPtr attr,
  2770. const char *name1,
  2771. const char *name2)
  2772. {
  2773. xmlChar *des = NULL;
  2774. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
  2775. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2776. "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
  2777. BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
  2778. FREE_AND_NULL(des);
  2779. }
  2780. /**
  2781. * xmlSchemaPSimpleTypeErr:
  2782. * @ctxt: the schema validation context
  2783. * @error: the error code
  2784. * @type: the type specifier
  2785. * @ownerDes: the designation of the owner
  2786. * @ownerItem: the schema object if existent
  2787. * @node: the validated node
  2788. * @value: the validated value
  2789. *
  2790. * Reports a simple type validation error.
  2791. * TODO: Should this report the value of an element as well?
  2792. */
  2793. static void
  2794. xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  2795. xmlParserErrors error,
  2796. xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
  2797. xmlNodePtr node,
  2798. xmlSchemaTypePtr type,
  2799. const char *expected,
  2800. const xmlChar *value,
  2801. const char *message,
  2802. const xmlChar *str1,
  2803. const xmlChar *str2)
  2804. {
  2805. xmlChar *msg = NULL;
  2806. xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
  2807. if (message == NULL) {
  2808. /*
  2809. * Use default messages.
  2810. */
  2811. if (type != NULL) {
  2812. if (node->type == XML_ATTRIBUTE_NODE)
  2813. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2814. else
  2815. msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
  2816. "valid value of ");
  2817. if (! xmlSchemaIsGlobalItem(type))
  2818. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2819. else
  2820. msg = xmlStrcat(msg, BAD_CAST "the ");
  2821. if (WXS_IS_ATOMIC(type))
  2822. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2823. else if (WXS_IS_LIST(type))
  2824. msg = xmlStrcat(msg, BAD_CAST "list type");
  2825. else if (WXS_IS_UNION(type))
  2826. msg = xmlStrcat(msg, BAD_CAST "union type");
  2827. if (xmlSchemaIsGlobalItem(type)) {
  2828. xmlChar *str = NULL;
  2829. msg = xmlStrcat(msg, BAD_CAST " '");
  2830. if (type->builtInType != 0) {
  2831. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2832. msg = xmlStrcat(msg, type->name);
  2833. } else
  2834. msg = xmlStrcat(msg,
  2835. xmlSchemaFormatQName(&str,
  2836. type->targetNamespace, type->name));
  2837. msg = xmlStrcat(msg, BAD_CAST "'.");
  2838. FREE_AND_NULL(str);
  2839. }
  2840. } else {
  2841. if (node->type == XML_ATTRIBUTE_NODE)
  2842. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
  2843. else
  2844. msg = xmlStrcat(msg, BAD_CAST "The character content is not "
  2845. "valid.");
  2846. }
  2847. if (expected) {
  2848. msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  2849. msg = xmlStrcat(msg, BAD_CAST expected);
  2850. msg = xmlStrcat(msg, BAD_CAST "'.\n");
  2851. } else
  2852. msg = xmlStrcat(msg, BAD_CAST "\n");
  2853. if (node->type == XML_ATTRIBUTE_NODE)
  2854. xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
  2855. else
  2856. xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
  2857. } else {
  2858. msg = xmlStrcat(msg, BAD_CAST message);
  2859. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2860. xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
  2861. (const char*) msg, str1, str2, NULL, NULL, NULL);
  2862. }
  2863. /* Cleanup. */
  2864. FREE_AND_NULL(msg)
  2865. }
  2866. /**
  2867. * xmlSchemaPContentErr:
  2868. * @ctxt: the schema parser context
  2869. * @error: the error code
  2870. * @onwerDes: the designation of the holder of the content
  2871. * @ownerItem: the owner item of the holder of the content
  2872. * @ownerElem: the node of the holder of the content
  2873. * @child: the invalid child node
  2874. * @message: the optional error message
  2875. * @content: the optional string describing the correct content
  2876. *
  2877. * Reports an error concerning the content of a schema element.
  2878. */
  2879. static void
  2880. xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
  2881. xmlParserErrors error,
  2882. xmlSchemaBasicItemPtr ownerItem,
  2883. xmlNodePtr ownerElem,
  2884. xmlNodePtr child,
  2885. const char *message,
  2886. const char *content)
  2887. {
  2888. xmlChar *des = NULL;
  2889. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2890. if (message != NULL)
  2891. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2892. "%s: %s.\n",
  2893. BAD_CAST des, BAD_CAST message);
  2894. else {
  2895. if (content != NULL) {
  2896. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2897. "%s: The content is not valid. Expected is %s.\n",
  2898. BAD_CAST des, BAD_CAST content);
  2899. } else {
  2900. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2901. "%s: The content is not valid.\n",
  2902. BAD_CAST des, NULL);
  2903. }
  2904. }
  2905. FREE_AND_NULL(des)
  2906. }
  2907. /************************************************************************
  2908. * *
  2909. * Streamable error functions *
  2910. * *
  2911. ************************************************************************/
  2912. /************************************************************************
  2913. * *
  2914. * Validation helper functions *
  2915. * *
  2916. ************************************************************************/
  2917. /************************************************************************
  2918. * *
  2919. * Allocation functions *
  2920. * *
  2921. ************************************************************************/
  2922. /**
  2923. * xmlSchemaNewSchemaForParserCtxt:
  2924. * @ctxt: a schema validation context
  2925. *
  2926. * Allocate a new Schema structure.
  2927. *
  2928. * Returns the newly allocated structure or NULL in case or error
  2929. */
  2930. static xmlSchemaPtr
  2931. xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
  2932. {
  2933. xmlSchemaPtr ret;
  2934. ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
  2935. if (ret == NULL) {
  2936. xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
  2937. return (NULL);
  2938. }
  2939. memset(ret, 0, sizeof(xmlSchema));
  2940. ret->dict = ctxt->dict;
  2941. xmlDictReference(ret->dict);
  2942. return (ret);
  2943. }
  2944. /**
  2945. * xmlSchemaNewFacet:
  2946. *
  2947. * Allocate a new Facet structure.
  2948. *
  2949. * Returns the newly allocated structure or NULL in case or error
  2950. */
  2951. xmlSchemaFacetPtr
  2952. xmlSchemaNewFacet(void)
  2953. {
  2954. xmlSchemaFacetPtr ret;
  2955. ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
  2956. if (ret == NULL) {
  2957. return (NULL);
  2958. }
  2959. memset(ret, 0, sizeof(xmlSchemaFacet));
  2960. return (ret);
  2961. }
  2962. /**
  2963. * xmlSchemaNewAnnot:
  2964. * @ctxt: a schema validation context
  2965. * @node: a node
  2966. *
  2967. * Allocate a new annotation structure.
  2968. *
  2969. * Returns the newly allocated structure or NULL in case or error
  2970. */
  2971. static xmlSchemaAnnotPtr
  2972. xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  2973. {
  2974. xmlSchemaAnnotPtr ret;
  2975. ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
  2976. if (ret == NULL) {
  2977. xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
  2978. return (NULL);
  2979. }
  2980. memset(ret, 0, sizeof(xmlSchemaAnnot));
  2981. ret->content = node;
  2982. return (ret);
  2983. }
  2984. static xmlSchemaItemListPtr
  2985. xmlSchemaItemListCreate(void)
  2986. {
  2987. xmlSchemaItemListPtr ret;
  2988. ret = xmlMalloc(sizeof(xmlSchemaItemList));
  2989. if (ret == NULL) {
  2990. xmlSchemaPErrMemory(NULL,
  2991. "allocating an item list structure", NULL);
  2992. return (NULL);
  2993. }
  2994. memset(ret, 0, sizeof(xmlSchemaItemList));
  2995. return (ret);
  2996. }
  2997. static void
  2998. xmlSchemaItemListClear(xmlSchemaItemListPtr list)
  2999. {
  3000. if (list->items != NULL) {
  3001. xmlFree(list->items);
  3002. list->items = NULL;
  3003. }
  3004. list->nbItems = 0;
  3005. list->sizeItems = 0;
  3006. }
  3007. static int
  3008. xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
  3009. {
  3010. if (list->items == NULL) {
  3011. list->items = (void **) xmlMalloc(
  3012. 20 * sizeof(void *));
  3013. if (list->items == NULL) {
  3014. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3015. return(-1);
  3016. }
  3017. list->sizeItems = 20;
  3018. } else if (list->sizeItems <= list->nbItems) {
  3019. list->sizeItems *= 2;
  3020. list->items = (void **) xmlRealloc(list->items,
  3021. list->sizeItems * sizeof(void *));
  3022. if (list->items == NULL) {
  3023. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3024. list->sizeItems = 0;
  3025. return(-1);
  3026. }
  3027. }
  3028. list->items[list->nbItems++] = item;
  3029. return(0);
  3030. }
  3031. static int
  3032. xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
  3033. int initialSize,
  3034. void *item)
  3035. {
  3036. if (list->items == NULL) {
  3037. if (initialSize <= 0)
  3038. initialSize = 1;
  3039. list->items = (void **) xmlMalloc(
  3040. initialSize * sizeof(void *));
  3041. if (list->items == NULL) {
  3042. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3043. return(-1);
  3044. }
  3045. list->sizeItems = initialSize;
  3046. } else if (list->sizeItems <= list->nbItems) {
  3047. list->sizeItems *= 2;
  3048. list->items = (void **) xmlRealloc(list->items,
  3049. list->sizeItems * sizeof(void *));
  3050. if (list->items == NULL) {
  3051. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3052. list->sizeItems = 0;
  3053. return(-1);
  3054. }
  3055. }
  3056. list->items[list->nbItems++] = item;
  3057. return(0);
  3058. }
  3059. static int
  3060. xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
  3061. {
  3062. if (list->items == NULL) {
  3063. list->items = (void **) xmlMalloc(
  3064. 20 * sizeof(void *));
  3065. if (list->items == NULL) {
  3066. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3067. return(-1);
  3068. }
  3069. list->sizeItems = 20;
  3070. } else if (list->sizeItems <= list->nbItems) {
  3071. list->sizeItems *= 2;
  3072. list->items = (void **) xmlRealloc(list->items,
  3073. list->sizeItems * sizeof(void *));
  3074. if (list->items == NULL) {
  3075. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3076. list->sizeItems = 0;
  3077. return(-1);
  3078. }
  3079. }
  3080. /*
  3081. * Just append if the index is greater/equal than the item count.
  3082. */
  3083. if (idx >= list->nbItems) {
  3084. list->items[list->nbItems++] = item;
  3085. } else {
  3086. int i;
  3087. for (i = list->nbItems; i > idx; i--)
  3088. list->items[i] = list->items[i-1];
  3089. list->items[idx] = item;
  3090. list->nbItems++;
  3091. }
  3092. return(0);
  3093. }
  3094. #if 0 /* enable if ever needed */
  3095. static int
  3096. xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
  3097. int initialSize,
  3098. void *item,
  3099. int idx)
  3100. {
  3101. if (list->items == NULL) {
  3102. if (initialSize <= 0)
  3103. initialSize = 1;
  3104. list->items = (void **) xmlMalloc(
  3105. initialSize * sizeof(void *));
  3106. if (list->items == NULL) {
  3107. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3108. return(-1);
  3109. }
  3110. list->sizeItems = initialSize;
  3111. } else if (list->sizeItems <= list->nbItems) {
  3112. list->sizeItems *= 2;
  3113. list->items = (void **) xmlRealloc(list->items,
  3114. list->sizeItems * sizeof(void *));
  3115. if (list->items == NULL) {
  3116. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3117. list->sizeItems = 0;
  3118. return(-1);
  3119. }
  3120. }
  3121. /*
  3122. * Just append if the index is greater/equal than the item count.
  3123. */
  3124. if (idx >= list->nbItems) {
  3125. list->items[list->nbItems++] = item;
  3126. } else {
  3127. int i;
  3128. for (i = list->nbItems; i > idx; i--)
  3129. list->items[i] = list->items[i-1];
  3130. list->items[idx] = item;
  3131. list->nbItems++;
  3132. }
  3133. return(0);
  3134. }
  3135. #endif
  3136. static int
  3137. xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
  3138. {
  3139. int i;
  3140. if ((list->items == NULL) || (idx >= list->nbItems)) {
  3141. xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
  3142. "index error.\n");
  3143. return(-1);
  3144. }
  3145. if (list->nbItems == 1) {
  3146. /* TODO: Really free the list? */
  3147. xmlFree(list->items);
  3148. list->items = NULL;
  3149. list->nbItems = 0;
  3150. list->sizeItems = 0;
  3151. } else if (list->nbItems -1 == idx) {
  3152. list->nbItems--;
  3153. } else {
  3154. for (i = idx; i < list->nbItems -1; i++)
  3155. list->items[i] = list->items[i+1];
  3156. list->nbItems--;
  3157. }
  3158. return(0);
  3159. }
  3160. /**
  3161. * xmlSchemaItemListFree:
  3162. * @annot: a schema type structure
  3163. *
  3164. * Deallocate a annotation structure
  3165. */
  3166. static void
  3167. xmlSchemaItemListFree(xmlSchemaItemListPtr list)
  3168. {
  3169. if (list == NULL)
  3170. return;
  3171. if (list->items != NULL)
  3172. xmlFree(list->items);
  3173. xmlFree(list);
  3174. }
  3175. static void
  3176. xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
  3177. {
  3178. if (bucket == NULL)
  3179. return;
  3180. if (bucket->globals != NULL) {
  3181. xmlSchemaComponentListFree(bucket->globals);
  3182. xmlSchemaItemListFree(bucket->globals);
  3183. }
  3184. if (bucket->locals != NULL) {
  3185. xmlSchemaComponentListFree(bucket->locals);
  3186. xmlSchemaItemListFree(bucket->locals);
  3187. }
  3188. if (bucket->relations != NULL) {
  3189. xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
  3190. do {
  3191. prev = cur;
  3192. cur = cur->next;
  3193. xmlFree(prev);
  3194. } while (cur != NULL);
  3195. }
  3196. if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
  3197. xmlFreeDoc(bucket->doc);
  3198. }
  3199. if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
  3200. if (WXS_IMPBUCKET(bucket)->schema != NULL)
  3201. xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
  3202. }
  3203. xmlFree(bucket);
  3204. }
  3205. static xmlSchemaBucketPtr
  3206. xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
  3207. int type, const xmlChar *targetNamespace)
  3208. {
  3209. xmlSchemaBucketPtr ret;
  3210. int size;
  3211. xmlSchemaPtr mainSchema;
  3212. if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
  3213. PERROR_INT("xmlSchemaBucketCreate",
  3214. "no main schema on constructor");
  3215. return(NULL);
  3216. }
  3217. mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
  3218. /* Create the schema bucket. */
  3219. if (WXS_IS_BUCKET_INCREDEF(type))
  3220. size = sizeof(xmlSchemaInclude);
  3221. else
  3222. size = sizeof(xmlSchemaImport);
  3223. ret = (xmlSchemaBucketPtr) xmlMalloc(size);
  3224. if (ret == NULL) {
  3225. xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
  3226. return(NULL);
  3227. }
  3228. memset(ret, 0, size);
  3229. ret->targetNamespace = targetNamespace;
  3230. ret->type = type;
  3231. ret->globals = xmlSchemaItemListCreate();
  3232. if (ret->globals == NULL) {
  3233. xmlFree(ret);
  3234. return(NULL);
  3235. }
  3236. ret->locals = xmlSchemaItemListCreate();
  3237. if (ret->locals == NULL) {
  3238. xmlFree(ret);
  3239. return(NULL);
  3240. }
  3241. /*
  3242. * The following will assure that only the first bucket is marked as
  3243. * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
  3244. * For each following import buckets an xmlSchema will be created.
  3245. * An xmlSchema will be created for every distinct targetNamespace.
  3246. * We assign the targetNamespace to the schemata here.
  3247. */
  3248. if (! WXS_HAS_BUCKETS(pctxt)) {
  3249. if (WXS_IS_BUCKET_INCREDEF(type)) {
  3250. PERROR_INT("xmlSchemaBucketCreate",
  3251. "first bucket but it's an include or redefine");
  3252. xmlSchemaBucketFree(ret);
  3253. return(NULL);
  3254. }
  3255. /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
  3256. ret->type = XML_SCHEMA_SCHEMA_MAIN;
  3257. /* Point to the *main* schema. */
  3258. WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
  3259. WXS_IMPBUCKET(ret)->schema = mainSchema;
  3260. /*
  3261. * Ensure that the main schema gets a targetNamespace.
  3262. */
  3263. mainSchema->targetNamespace = targetNamespace;
  3264. } else {
  3265. if (type == XML_SCHEMA_SCHEMA_MAIN) {
  3266. PERROR_INT("xmlSchemaBucketCreate",
  3267. "main bucket but it's not the first one");
  3268. xmlSchemaBucketFree(ret);
  3269. return(NULL);
  3270. } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
  3271. /*
  3272. * Create a schema for imports and assign the
  3273. * targetNamespace.
  3274. */
  3275. WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
  3276. if (WXS_IMPBUCKET(ret)->schema == NULL) {
  3277. xmlSchemaBucketFree(ret);
  3278. return(NULL);
  3279. }
  3280. WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
  3281. }
  3282. }
  3283. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  3284. int res;
  3285. /*
  3286. * Imports go into the "schemasImports" slot of the main *schema*.
  3287. * Note that we create an import entry for the main schema as well; i.e.,
  3288. * even if there's only one schema, we'll get an import.
  3289. */
  3290. if (mainSchema->schemasImports == NULL) {
  3291. mainSchema->schemasImports = xmlHashCreateDict(5,
  3292. WXS_CONSTRUCTOR(pctxt)->dict);
  3293. if (mainSchema->schemasImports == NULL) {
  3294. xmlSchemaBucketFree(ret);
  3295. return(NULL);
  3296. }
  3297. }
  3298. if (targetNamespace == NULL)
  3299. res = xmlHashAddEntry(mainSchema->schemasImports,
  3300. XML_SCHEMAS_NO_NAMESPACE, ret);
  3301. else
  3302. res = xmlHashAddEntry(mainSchema->schemasImports,
  3303. targetNamespace, ret);
  3304. if (res != 0) {
  3305. PERROR_INT("xmlSchemaBucketCreate",
  3306. "failed to add the schema bucket to the hash");
  3307. xmlSchemaBucketFree(ret);
  3308. return(NULL);
  3309. }
  3310. } else {
  3311. /* Set the @ownerImport of an include bucket. */
  3312. if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
  3313. WXS_INCBUCKET(ret)->ownerImport =
  3314. WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
  3315. else
  3316. WXS_INCBUCKET(ret)->ownerImport =
  3317. WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
  3318. /* Includes got into the "includes" slot of the *main* schema. */
  3319. if (mainSchema->includes == NULL) {
  3320. mainSchema->includes = xmlSchemaItemListCreate();
  3321. if (mainSchema->includes == NULL) {
  3322. xmlSchemaBucketFree(ret);
  3323. return(NULL);
  3324. }
  3325. }
  3326. xmlSchemaItemListAdd(mainSchema->includes, ret);
  3327. }
  3328. /*
  3329. * Add to list of all buckets; this is used for lookup
  3330. * during schema construction time only.
  3331. */
  3332. if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
  3333. return(NULL);
  3334. return(ret);
  3335. }
  3336. static int
  3337. xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
  3338. {
  3339. if (*list == NULL) {
  3340. *list = xmlSchemaItemListCreate();
  3341. if (*list == NULL)
  3342. return(-1);
  3343. }
  3344. xmlSchemaItemListAddSize(*list, initialSize, item);
  3345. return(0);
  3346. }
  3347. /**
  3348. * xmlSchemaFreeAnnot:
  3349. * @annot: a schema type structure
  3350. *
  3351. * Deallocate a annotation structure
  3352. */
  3353. static void
  3354. xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
  3355. {
  3356. if (annot == NULL)
  3357. return;
  3358. if (annot->next == NULL) {
  3359. xmlFree(annot);
  3360. } else {
  3361. xmlSchemaAnnotPtr prev;
  3362. do {
  3363. prev = annot;
  3364. annot = annot->next;
  3365. xmlFree(prev);
  3366. } while (annot != NULL);
  3367. }
  3368. }
  3369. /**
  3370. * xmlSchemaFreeNotation:
  3371. * @schema: a schema notation structure
  3372. *
  3373. * Deallocate a Schema Notation structure.
  3374. */
  3375. static void
  3376. xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
  3377. {
  3378. if (nota == NULL)
  3379. return;
  3380. xmlFree(nota);
  3381. }
  3382. /**
  3383. * xmlSchemaFreeAttribute:
  3384. * @attr: an attribute declaration
  3385. *
  3386. * Deallocates an attribute declaration structure.
  3387. */
  3388. static void
  3389. xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
  3390. {
  3391. if (attr == NULL)
  3392. return;
  3393. if (attr->annot != NULL)
  3394. xmlSchemaFreeAnnot(attr->annot);
  3395. if (attr->defVal != NULL)
  3396. xmlSchemaFreeValue(attr->defVal);
  3397. xmlFree(attr);
  3398. }
  3399. /**
  3400. * xmlSchemaFreeAttributeUse:
  3401. * @use: an attribute use
  3402. *
  3403. * Deallocates an attribute use structure.
  3404. */
  3405. static void
  3406. xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
  3407. {
  3408. if (use == NULL)
  3409. return;
  3410. if (use->annot != NULL)
  3411. xmlSchemaFreeAnnot(use->annot);
  3412. if (use->defVal != NULL)
  3413. xmlSchemaFreeValue(use->defVal);
  3414. xmlFree(use);
  3415. }
  3416. /**
  3417. * xmlSchemaFreeAttributeUseProhib:
  3418. * @prohib: an attribute use prohibition
  3419. *
  3420. * Deallocates an attribute use structure.
  3421. */
  3422. static void
  3423. xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
  3424. {
  3425. if (prohib == NULL)
  3426. return;
  3427. xmlFree(prohib);
  3428. }
  3429. /**
  3430. * xmlSchemaFreeWildcardNsSet:
  3431. * set: a schema wildcard namespace
  3432. *
  3433. * Deallocates a list of wildcard constraint structures.
  3434. */
  3435. static void
  3436. xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
  3437. {
  3438. xmlSchemaWildcardNsPtr next;
  3439. while (set != NULL) {
  3440. next = set->next;
  3441. xmlFree(set);
  3442. set = next;
  3443. }
  3444. }
  3445. /**
  3446. * xmlSchemaFreeWildcard:
  3447. * @wildcard: a wildcard structure
  3448. *
  3449. * Deallocates a wildcard structure.
  3450. */
  3451. void
  3452. xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
  3453. {
  3454. if (wildcard == NULL)
  3455. return;
  3456. if (wildcard->annot != NULL)
  3457. xmlSchemaFreeAnnot(wildcard->annot);
  3458. if (wildcard->nsSet != NULL)
  3459. xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
  3460. if (wildcard->negNsSet != NULL)
  3461. xmlFree(wildcard->negNsSet);
  3462. xmlFree(wildcard);
  3463. }
  3464. /**
  3465. * xmlSchemaFreeAttributeGroup:
  3466. * @schema: a schema attribute group structure
  3467. *
  3468. * Deallocate a Schema Attribute Group structure.
  3469. */
  3470. static void
  3471. xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
  3472. {
  3473. if (attrGr == NULL)
  3474. return;
  3475. if (attrGr->annot != NULL)
  3476. xmlSchemaFreeAnnot(attrGr->annot);
  3477. if (attrGr->attrUses != NULL)
  3478. xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
  3479. xmlFree(attrGr);
  3480. }
  3481. /**
  3482. * xmlSchemaFreeQNameRef:
  3483. * @item: a QName reference structure
  3484. *
  3485. * Deallocatea a QName reference structure.
  3486. */
  3487. static void
  3488. xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
  3489. {
  3490. xmlFree(item);
  3491. }
  3492. /**
  3493. * xmlSchemaFreeTypeLinkList:
  3494. * @alink: a type link
  3495. *
  3496. * Deallocate a list of types.
  3497. */
  3498. static void
  3499. xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
  3500. {
  3501. xmlSchemaTypeLinkPtr next;
  3502. while (link != NULL) {
  3503. next = link->next;
  3504. xmlFree(link);
  3505. link = next;
  3506. }
  3507. }
  3508. static void
  3509. xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
  3510. {
  3511. xmlSchemaIDCStateObjPtr next;
  3512. while (sto != NULL) {
  3513. next = sto->next;
  3514. if (sto->history != NULL)
  3515. xmlFree(sto->history);
  3516. if (sto->xpathCtxt != NULL)
  3517. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  3518. xmlFree(sto);
  3519. sto = next;
  3520. }
  3521. }
  3522. /**
  3523. * xmlSchemaFreeIDC:
  3524. * @idc: a identity-constraint definition
  3525. *
  3526. * Deallocates an identity-constraint definition.
  3527. */
  3528. static void
  3529. xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
  3530. {
  3531. xmlSchemaIDCSelectPtr cur, prev;
  3532. if (idcDef == NULL)
  3533. return;
  3534. if (idcDef->annot != NULL)
  3535. xmlSchemaFreeAnnot(idcDef->annot);
  3536. /* Selector */
  3537. if (idcDef->selector != NULL) {
  3538. if (idcDef->selector->xpathComp != NULL)
  3539. xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
  3540. xmlFree(idcDef->selector);
  3541. }
  3542. /* Fields */
  3543. if (idcDef->fields != NULL) {
  3544. cur = idcDef->fields;
  3545. do {
  3546. prev = cur;
  3547. cur = cur->next;
  3548. if (prev->xpathComp != NULL)
  3549. xmlFreePattern((xmlPatternPtr) prev->xpathComp);
  3550. xmlFree(prev);
  3551. } while (cur != NULL);
  3552. }
  3553. xmlFree(idcDef);
  3554. }
  3555. /**
  3556. * xmlSchemaFreeElement:
  3557. * @schema: a schema element structure
  3558. *
  3559. * Deallocate a Schema Element structure.
  3560. */
  3561. static void
  3562. xmlSchemaFreeElement(xmlSchemaElementPtr elem)
  3563. {
  3564. if (elem == NULL)
  3565. return;
  3566. if (elem->annot != NULL)
  3567. xmlSchemaFreeAnnot(elem->annot);
  3568. if (elem->contModel != NULL)
  3569. xmlRegFreeRegexp(elem->contModel);
  3570. if (elem->defVal != NULL)
  3571. xmlSchemaFreeValue(elem->defVal);
  3572. xmlFree(elem);
  3573. }
  3574. /**
  3575. * xmlSchemaFreeFacet:
  3576. * @facet: a schema facet structure
  3577. *
  3578. * Deallocate a Schema Facet structure.
  3579. */
  3580. void
  3581. xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
  3582. {
  3583. if (facet == NULL)
  3584. return;
  3585. if (facet->val != NULL)
  3586. xmlSchemaFreeValue(facet->val);
  3587. if (facet->regexp != NULL)
  3588. xmlRegFreeRegexp(facet->regexp);
  3589. if (facet->annot != NULL)
  3590. xmlSchemaFreeAnnot(facet->annot);
  3591. xmlFree(facet);
  3592. }
  3593. /**
  3594. * xmlSchemaFreeType:
  3595. * @type: a schema type structure
  3596. *
  3597. * Deallocate a Schema Type structure.
  3598. */
  3599. void
  3600. xmlSchemaFreeType(xmlSchemaTypePtr type)
  3601. {
  3602. if (type == NULL)
  3603. return;
  3604. if (type->annot != NULL)
  3605. xmlSchemaFreeAnnot(type->annot);
  3606. if (type->facets != NULL) {
  3607. xmlSchemaFacetPtr facet, next;
  3608. facet = type->facets;
  3609. while (facet != NULL) {
  3610. next = facet->next;
  3611. xmlSchemaFreeFacet(facet);
  3612. facet = next;
  3613. }
  3614. }
  3615. if (type->attrUses != NULL)
  3616. xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
  3617. if (type->memberTypes != NULL)
  3618. xmlSchemaFreeTypeLinkList(type->memberTypes);
  3619. if (type->facetSet != NULL) {
  3620. xmlSchemaFacetLinkPtr next, link;
  3621. link = type->facetSet;
  3622. do {
  3623. next = link->next;
  3624. xmlFree(link);
  3625. link = next;
  3626. } while (link != NULL);
  3627. }
  3628. if (type->contModel != NULL)
  3629. xmlRegFreeRegexp(type->contModel);
  3630. xmlFree(type);
  3631. }
  3632. /**
  3633. * xmlSchemaFreeModelGroupDef:
  3634. * @item: a schema model group definition
  3635. *
  3636. * Deallocates a schema model group definition.
  3637. */
  3638. static void
  3639. xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
  3640. {
  3641. if (item->annot != NULL)
  3642. xmlSchemaFreeAnnot(item->annot);
  3643. xmlFree(item);
  3644. }
  3645. /**
  3646. * xmlSchemaFreeModelGroup:
  3647. * @item: a schema model group
  3648. *
  3649. * Deallocates a schema model group structure.
  3650. */
  3651. static void
  3652. xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
  3653. {
  3654. if (item->annot != NULL)
  3655. xmlSchemaFreeAnnot(item->annot);
  3656. xmlFree(item);
  3657. }
  3658. static void
  3659. xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
  3660. {
  3661. if ((list == NULL) || (list->nbItems == 0))
  3662. return;
  3663. {
  3664. xmlSchemaTreeItemPtr item;
  3665. xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
  3666. int i;
  3667. for (i = 0; i < list->nbItems; i++) {
  3668. item = items[i];
  3669. if (item == NULL)
  3670. continue;
  3671. switch (item->type) {
  3672. case XML_SCHEMA_TYPE_SIMPLE:
  3673. case XML_SCHEMA_TYPE_COMPLEX:
  3674. xmlSchemaFreeType((xmlSchemaTypePtr) item);
  3675. break;
  3676. case XML_SCHEMA_TYPE_ATTRIBUTE:
  3677. xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
  3678. break;
  3679. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  3680. xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
  3681. break;
  3682. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  3683. xmlSchemaFreeAttributeUseProhib(
  3684. (xmlSchemaAttributeUseProhibPtr) item);
  3685. break;
  3686. case XML_SCHEMA_TYPE_ELEMENT:
  3687. xmlSchemaFreeElement((xmlSchemaElementPtr) item);
  3688. break;
  3689. case XML_SCHEMA_TYPE_PARTICLE:
  3690. if (item->annot != NULL)
  3691. xmlSchemaFreeAnnot(item->annot);
  3692. xmlFree(item);
  3693. break;
  3694. case XML_SCHEMA_TYPE_SEQUENCE:
  3695. case XML_SCHEMA_TYPE_CHOICE:
  3696. case XML_SCHEMA_TYPE_ALL:
  3697. xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
  3698. break;
  3699. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  3700. xmlSchemaFreeAttributeGroup(
  3701. (xmlSchemaAttributeGroupPtr) item);
  3702. break;
  3703. case XML_SCHEMA_TYPE_GROUP:
  3704. xmlSchemaFreeModelGroupDef(
  3705. (xmlSchemaModelGroupDefPtr) item);
  3706. break;
  3707. case XML_SCHEMA_TYPE_ANY:
  3708. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  3709. xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
  3710. break;
  3711. case XML_SCHEMA_TYPE_IDC_KEY:
  3712. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  3713. case XML_SCHEMA_TYPE_IDC_KEYREF:
  3714. xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
  3715. break;
  3716. case XML_SCHEMA_TYPE_NOTATION:
  3717. xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
  3718. break;
  3719. case XML_SCHEMA_EXTRA_QNAMEREF:
  3720. xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
  3721. break;
  3722. default: {
  3723. /* TODO: This should never be hit. */
  3724. xmlSchemaPSimpleInternalErr(NULL,
  3725. "Internal error: xmlSchemaComponentListFree, "
  3726. "unexpected component type '%s'\n",
  3727. (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
  3728. }
  3729. break;
  3730. }
  3731. }
  3732. list->nbItems = 0;
  3733. }
  3734. }
  3735. /**
  3736. * xmlSchemaFree:
  3737. * @schema: a schema structure
  3738. *
  3739. * Deallocate a Schema structure.
  3740. */
  3741. void
  3742. xmlSchemaFree(xmlSchemaPtr schema)
  3743. {
  3744. if (schema == NULL)
  3745. return;
  3746. /* @volatiles is not used anymore :-/ */
  3747. if (schema->volatiles != NULL)
  3748. TODO
  3749. /*
  3750. * Note that those slots are not responsible for freeing
  3751. * schema components anymore; this will now be done by
  3752. * the schema buckets.
  3753. */
  3754. if (schema->notaDecl != NULL)
  3755. xmlHashFree(schema->notaDecl, NULL);
  3756. if (schema->attrDecl != NULL)
  3757. xmlHashFree(schema->attrDecl, NULL);
  3758. if (schema->attrgrpDecl != NULL)
  3759. xmlHashFree(schema->attrgrpDecl, NULL);
  3760. if (schema->elemDecl != NULL)
  3761. xmlHashFree(schema->elemDecl, NULL);
  3762. if (schema->typeDecl != NULL)
  3763. xmlHashFree(schema->typeDecl, NULL);
  3764. if (schema->groupDecl != NULL)
  3765. xmlHashFree(schema->groupDecl, NULL);
  3766. if (schema->idcDef != NULL)
  3767. xmlHashFree(schema->idcDef, NULL);
  3768. if (schema->schemasImports != NULL)
  3769. xmlHashFree(schema->schemasImports,
  3770. (xmlHashDeallocator) xmlSchemaBucketFree);
  3771. if (schema->includes != NULL) {
  3772. xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
  3773. int i;
  3774. for (i = 0; i < list->nbItems; i++) {
  3775. xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
  3776. }
  3777. xmlSchemaItemListFree(list);
  3778. }
  3779. if (schema->annot != NULL)
  3780. xmlSchemaFreeAnnot(schema->annot);
  3781. /* Never free the doc here, since this will be done by the buckets. */
  3782. xmlDictFree(schema->dict);
  3783. xmlFree(schema);
  3784. }
  3785. /************************************************************************
  3786. * *
  3787. * Debug functions *
  3788. * *
  3789. ************************************************************************/
  3790. #ifdef LIBXML_OUTPUT_ENABLED
  3791. static void
  3792. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
  3793. /**
  3794. * xmlSchemaElementDump:
  3795. * @elem: an element
  3796. * @output: the file output
  3797. *
  3798. * Dump the element
  3799. */
  3800. static void
  3801. xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
  3802. const xmlChar * name ATTRIBUTE_UNUSED,
  3803. const xmlChar * namespace ATTRIBUTE_UNUSED,
  3804. const xmlChar * context ATTRIBUTE_UNUSED)
  3805. {
  3806. if (elem == NULL)
  3807. return;
  3808. fprintf(output, "Element");
  3809. if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
  3810. fprintf(output, " (global)");
  3811. fprintf(output, ": '%s' ", elem->name);
  3812. if (namespace != NULL)
  3813. fprintf(output, "ns '%s'", namespace);
  3814. fprintf(output, "\n");
  3815. #if 0
  3816. if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
  3817. fprintf(output, " min %d ", elem->minOccurs);
  3818. if (elem->maxOccurs >= UNBOUNDED)
  3819. fprintf(output, "max: unbounded\n");
  3820. else if (elem->maxOccurs != 1)
  3821. fprintf(output, "max: %d\n", elem->maxOccurs);
  3822. else
  3823. fprintf(output, "\n");
  3824. }
  3825. #endif
  3826. /*
  3827. * Misc other properties.
  3828. */
  3829. if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
  3830. (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
  3831. (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
  3832. (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
  3833. fprintf(output, " props: ");
  3834. if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
  3835. fprintf(output, "[fixed] ");
  3836. if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
  3837. fprintf(output, "[default] ");
  3838. if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  3839. fprintf(output, "[abstract] ");
  3840. if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
  3841. fprintf(output, "[nillable] ");
  3842. fprintf(output, "\n");
  3843. }
  3844. /*
  3845. * Default/fixed value.
  3846. */
  3847. if (elem->value != NULL)
  3848. fprintf(output, " value: '%s'\n", elem->value);
  3849. /*
  3850. * Type.
  3851. */
  3852. if (elem->namedType != NULL) {
  3853. fprintf(output, " type: '%s' ", elem->namedType);
  3854. if (elem->namedTypeNs != NULL)
  3855. fprintf(output, "ns '%s'\n", elem->namedTypeNs);
  3856. else
  3857. fprintf(output, "\n");
  3858. } else if (elem->subtypes != NULL) {
  3859. /*
  3860. * Dump local types.
  3861. */
  3862. xmlSchemaTypeDump(elem->subtypes, output);
  3863. }
  3864. /*
  3865. * Substitution group.
  3866. */
  3867. if (elem->substGroup != NULL) {
  3868. fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
  3869. if (elem->substGroupNs != NULL)
  3870. fprintf(output, "ns '%s'\n", elem->substGroupNs);
  3871. else
  3872. fprintf(output, "\n");
  3873. }
  3874. }
  3875. /**
  3876. * xmlSchemaAnnotDump:
  3877. * @output: the file output
  3878. * @annot: a annotation
  3879. *
  3880. * Dump the annotation
  3881. */
  3882. static void
  3883. xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
  3884. {
  3885. xmlChar *content;
  3886. if (annot == NULL)
  3887. return;
  3888. content = xmlNodeGetContent(annot->content);
  3889. if (content != NULL) {
  3890. fprintf(output, " Annot: %s\n", content);
  3891. xmlFree(content);
  3892. } else
  3893. fprintf(output, " Annot: empty\n");
  3894. }
  3895. /**
  3896. * xmlSchemaContentModelDump:
  3897. * @particle: the schema particle
  3898. * @output: the file output
  3899. * @depth: the depth used for intentation
  3900. *
  3901. * Dump a SchemaType structure
  3902. */
  3903. static void
  3904. xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
  3905. {
  3906. xmlChar *str = NULL;
  3907. xmlSchemaTreeItemPtr term;
  3908. char shift[100];
  3909. int i;
  3910. if (particle == NULL)
  3911. return;
  3912. for (i = 0;((i < depth) && (i < 25));i++)
  3913. shift[2 * i] = shift[2 * i + 1] = ' ';
  3914. shift[2 * i] = shift[2 * i + 1] = 0;
  3915. fprintf(output, "%s", shift);
  3916. if (particle->children == NULL) {
  3917. fprintf(output, "MISSING particle term\n");
  3918. return;
  3919. }
  3920. term = particle->children;
  3921. if (term == NULL) {
  3922. fprintf(output, "(NULL)");
  3923. } else {
  3924. switch (term->type) {
  3925. case XML_SCHEMA_TYPE_ELEMENT:
  3926. fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
  3927. ((xmlSchemaElementPtr)term)->targetNamespace,
  3928. ((xmlSchemaElementPtr)term)->name));
  3929. FREE_AND_NULL(str);
  3930. break;
  3931. case XML_SCHEMA_TYPE_SEQUENCE:
  3932. fprintf(output, "SEQUENCE");
  3933. break;
  3934. case XML_SCHEMA_TYPE_CHOICE:
  3935. fprintf(output, "CHOICE");
  3936. break;
  3937. case XML_SCHEMA_TYPE_ALL:
  3938. fprintf(output, "ALL");
  3939. break;
  3940. case XML_SCHEMA_TYPE_ANY:
  3941. fprintf(output, "ANY");
  3942. break;
  3943. default:
  3944. fprintf(output, "UNKNOWN\n");
  3945. return;
  3946. }
  3947. }
  3948. if (particle->minOccurs != 1)
  3949. fprintf(output, " min: %d", particle->minOccurs);
  3950. if (particle->maxOccurs >= UNBOUNDED)
  3951. fprintf(output, " max: unbounded");
  3952. else if (particle->maxOccurs != 1)
  3953. fprintf(output, " max: %d", particle->maxOccurs);
  3954. fprintf(output, "\n");
  3955. if (term &&
  3956. ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  3957. (term->type == XML_SCHEMA_TYPE_CHOICE) ||
  3958. (term->type == XML_SCHEMA_TYPE_ALL)) &&
  3959. (term->children != NULL)) {
  3960. xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
  3961. output, depth +1);
  3962. }
  3963. if (particle->next != NULL)
  3964. xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
  3965. output, depth);
  3966. }
  3967. /**
  3968. * xmlSchemaAttrUsesDump:
  3969. * @uses: attribute uses list
  3970. * @output: the file output
  3971. *
  3972. * Dumps a list of attribute use components.
  3973. */
  3974. static void
  3975. xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
  3976. {
  3977. xmlSchemaAttributeUsePtr use;
  3978. xmlSchemaAttributeUseProhibPtr prohib;
  3979. xmlSchemaQNameRefPtr ref;
  3980. const xmlChar *name, *tns;
  3981. xmlChar *str = NULL;
  3982. int i;
  3983. if ((uses == NULL) || (uses->nbItems == 0))
  3984. return;
  3985. fprintf(output, " attributes:\n");
  3986. for (i = 0; i < uses->nbItems; i++) {
  3987. use = uses->items[i];
  3988. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  3989. fprintf(output, " [prohibition] ");
  3990. prohib = (xmlSchemaAttributeUseProhibPtr) use;
  3991. name = prohib->name;
  3992. tns = prohib->targetNamespace;
  3993. } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
  3994. fprintf(output, " [reference] ");
  3995. ref = (xmlSchemaQNameRefPtr) use;
  3996. name = ref->name;
  3997. tns = ref->targetNamespace;
  3998. } else {
  3999. fprintf(output, " [use] ");
  4000. name = WXS_ATTRUSE_DECL_NAME(use);
  4001. tns = WXS_ATTRUSE_DECL_TNS(use);
  4002. }
  4003. fprintf(output, "'%s'\n",
  4004. (const char *) xmlSchemaFormatQName(&str, tns, name));
  4005. FREE_AND_NULL(str);
  4006. }
  4007. }
  4008. /**
  4009. * xmlSchemaTypeDump:
  4010. * @output: the file output
  4011. * @type: a type structure
  4012. *
  4013. * Dump a SchemaType structure
  4014. */
  4015. static void
  4016. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
  4017. {
  4018. if (type == NULL) {
  4019. fprintf(output, "Type: NULL\n");
  4020. return;
  4021. }
  4022. fprintf(output, "Type: ");
  4023. if (type->name != NULL)
  4024. fprintf(output, "'%s' ", type->name);
  4025. else
  4026. fprintf(output, "(no name) ");
  4027. if (type->targetNamespace != NULL)
  4028. fprintf(output, "ns '%s' ", type->targetNamespace);
  4029. switch (type->type) {
  4030. case XML_SCHEMA_TYPE_BASIC:
  4031. fprintf(output, "[basic] ");
  4032. break;
  4033. case XML_SCHEMA_TYPE_SIMPLE:
  4034. fprintf(output, "[simple] ");
  4035. break;
  4036. case XML_SCHEMA_TYPE_COMPLEX:
  4037. fprintf(output, "[complex] ");
  4038. break;
  4039. case XML_SCHEMA_TYPE_SEQUENCE:
  4040. fprintf(output, "[sequence] ");
  4041. break;
  4042. case XML_SCHEMA_TYPE_CHOICE:
  4043. fprintf(output, "[choice] ");
  4044. break;
  4045. case XML_SCHEMA_TYPE_ALL:
  4046. fprintf(output, "[all] ");
  4047. break;
  4048. case XML_SCHEMA_TYPE_UR:
  4049. fprintf(output, "[ur] ");
  4050. break;
  4051. case XML_SCHEMA_TYPE_RESTRICTION:
  4052. fprintf(output, "[restriction] ");
  4053. break;
  4054. case XML_SCHEMA_TYPE_EXTENSION:
  4055. fprintf(output, "[extension] ");
  4056. break;
  4057. default:
  4058. fprintf(output, "[unknown type %d] ", type->type);
  4059. break;
  4060. }
  4061. fprintf(output, "content: ");
  4062. switch (type->contentType) {
  4063. case XML_SCHEMA_CONTENT_UNKNOWN:
  4064. fprintf(output, "[unknown] ");
  4065. break;
  4066. case XML_SCHEMA_CONTENT_EMPTY:
  4067. fprintf(output, "[empty] ");
  4068. break;
  4069. case XML_SCHEMA_CONTENT_ELEMENTS:
  4070. fprintf(output, "[element] ");
  4071. break;
  4072. case XML_SCHEMA_CONTENT_MIXED:
  4073. fprintf(output, "[mixed] ");
  4074. break;
  4075. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  4076. /* not used. */
  4077. break;
  4078. case XML_SCHEMA_CONTENT_BASIC:
  4079. fprintf(output, "[basic] ");
  4080. break;
  4081. case XML_SCHEMA_CONTENT_SIMPLE:
  4082. fprintf(output, "[simple] ");
  4083. break;
  4084. case XML_SCHEMA_CONTENT_ANY:
  4085. fprintf(output, "[any] ");
  4086. break;
  4087. }
  4088. fprintf(output, "\n");
  4089. if (type->base != NULL) {
  4090. fprintf(output, " base type: '%s'", type->base);
  4091. if (type->baseNs != NULL)
  4092. fprintf(output, " ns '%s'\n", type->baseNs);
  4093. else
  4094. fprintf(output, "\n");
  4095. }
  4096. if (type->attrUses != NULL)
  4097. xmlSchemaAttrUsesDump(type->attrUses, output);
  4098. if (type->annot != NULL)
  4099. xmlSchemaAnnotDump(output, type->annot);
  4100. #ifdef DUMP_CONTENT_MODEL
  4101. if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
  4102. (type->subtypes != NULL)) {
  4103. xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
  4104. output, 1);
  4105. }
  4106. #endif
  4107. }
  4108. /**
  4109. * xmlSchemaDump:
  4110. * @output: the file output
  4111. * @schema: a schema structure
  4112. *
  4113. * Dump a Schema structure.
  4114. */
  4115. void
  4116. xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
  4117. {
  4118. if (output == NULL)
  4119. return;
  4120. if (schema == NULL) {
  4121. fprintf(output, "Schemas: NULL\n");
  4122. return;
  4123. }
  4124. fprintf(output, "Schemas: ");
  4125. if (schema->name != NULL)
  4126. fprintf(output, "%s, ", schema->name);
  4127. else
  4128. fprintf(output, "no name, ");
  4129. if (schema->targetNamespace != NULL)
  4130. fprintf(output, "%s", (const char *) schema->targetNamespace);
  4131. else
  4132. fprintf(output, "no target namespace");
  4133. fprintf(output, "\n");
  4134. if (schema->annot != NULL)
  4135. xmlSchemaAnnotDump(output, schema->annot);
  4136. xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
  4137. output);
  4138. xmlHashScanFull(schema->elemDecl,
  4139. (xmlHashScannerFull) xmlSchemaElementDump, output);
  4140. }
  4141. #ifdef DEBUG_IDC_NODE_TABLE
  4142. /**
  4143. * xmlSchemaDebugDumpIDCTable:
  4144. * @vctxt: the WXS validation context
  4145. *
  4146. * Displays the current IDC table for debug purposes.
  4147. */
  4148. static void
  4149. xmlSchemaDebugDumpIDCTable(FILE * output,
  4150. const xmlChar *namespaceName,
  4151. const xmlChar *localName,
  4152. xmlSchemaPSVIIDCBindingPtr bind)
  4153. {
  4154. xmlChar *str = NULL;
  4155. const xmlChar *value;
  4156. xmlSchemaPSVIIDCNodePtr tab;
  4157. xmlSchemaPSVIIDCKeyPtr key;
  4158. int i, j, res;
  4159. fprintf(output, "IDC: TABLES on '%s'\n",
  4160. xmlSchemaFormatQName(&str, namespaceName, localName));
  4161. FREE_AND_NULL(str)
  4162. if (bind == NULL)
  4163. return;
  4164. do {
  4165. fprintf(output, "IDC: BINDING '%s' (%d)\n",
  4166. xmlSchemaGetComponentQName(&str,
  4167. bind->definition), bind->nbNodes);
  4168. FREE_AND_NULL(str)
  4169. for (i = 0; i < bind->nbNodes; i++) {
  4170. tab = bind->nodeTable[i];
  4171. fprintf(output, " ( ");
  4172. for (j = 0; j < bind->definition->nbFields; j++) {
  4173. key = tab->keys[j];
  4174. if ((key != NULL) && (key->val != NULL)) {
  4175. res = xmlSchemaGetCanonValue(key->val, &value);
  4176. if (res >= 0)
  4177. fprintf(output, "'%s' ", value);
  4178. else
  4179. fprintf(output, "CANON-VALUE-FAILED ");
  4180. if (res == 0)
  4181. FREE_AND_NULL(value)
  4182. } else if (key != NULL)
  4183. fprintf(output, "(no val), ");
  4184. else
  4185. fprintf(output, "(key missing), ");
  4186. }
  4187. fprintf(output, ")\n");
  4188. }
  4189. if (bind->dupls && bind->dupls->nbItems) {
  4190. fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
  4191. for (i = 0; i < bind->dupls->nbItems; i++) {
  4192. tab = bind->dupls->items[i];
  4193. fprintf(output, " ( ");
  4194. for (j = 0; j < bind->definition->nbFields; j++) {
  4195. key = tab->keys[j];
  4196. if ((key != NULL) && (key->val != NULL)) {
  4197. res = xmlSchemaGetCanonValue(key->val, &value);
  4198. if (res >= 0)
  4199. fprintf(output, "'%s' ", value);
  4200. else
  4201. fprintf(output, "CANON-VALUE-FAILED ");
  4202. if (res == 0)
  4203. FREE_AND_NULL(value)
  4204. } else if (key != NULL)
  4205. fprintf(output, "(no val), ");
  4206. else
  4207. fprintf(output, "(key missing), ");
  4208. }
  4209. fprintf(output, ")\n");
  4210. }
  4211. }
  4212. bind = bind->next;
  4213. } while (bind != NULL);
  4214. }
  4215. #endif /* DEBUG_IDC */
  4216. #endif /* LIBXML_OUTPUT_ENABLED */
  4217. /************************************************************************
  4218. * *
  4219. * Utilities *
  4220. * *
  4221. ************************************************************************/
  4222. /**
  4223. * xmlSchemaGetPropNode:
  4224. * @node: the element node
  4225. * @name: the name of the attribute
  4226. *
  4227. * Seeks an attribute with a name of @name in
  4228. * no namespace.
  4229. *
  4230. * Returns the attribute or NULL if not present.
  4231. */
  4232. static xmlAttrPtr
  4233. xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
  4234. {
  4235. xmlAttrPtr prop;
  4236. if ((node == NULL) || (name == NULL))
  4237. return(NULL);
  4238. prop = node->properties;
  4239. while (prop != NULL) {
  4240. if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
  4241. return(prop);
  4242. prop = prop->next;
  4243. }
  4244. return (NULL);
  4245. }
  4246. /**
  4247. * xmlSchemaGetPropNodeNs:
  4248. * @node: the element node
  4249. * @uri: the uri
  4250. * @name: the name of the attribute
  4251. *
  4252. * Seeks an attribute with a local name of @name and
  4253. * a namespace URI of @uri.
  4254. *
  4255. * Returns the attribute or NULL if not present.
  4256. */
  4257. static xmlAttrPtr
  4258. xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
  4259. {
  4260. xmlAttrPtr prop;
  4261. if ((node == NULL) || (name == NULL))
  4262. return(NULL);
  4263. prop = node->properties;
  4264. while (prop != NULL) {
  4265. if ((prop->ns != NULL) &&
  4266. xmlStrEqual(prop->name, BAD_CAST name) &&
  4267. xmlStrEqual(prop->ns->href, BAD_CAST uri))
  4268. return(prop);
  4269. prop = prop->next;
  4270. }
  4271. return (NULL);
  4272. }
  4273. static const xmlChar *
  4274. xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  4275. {
  4276. xmlChar *val;
  4277. const xmlChar *ret;
  4278. val = xmlNodeGetContent(node);
  4279. if (val == NULL)
  4280. val = xmlStrdup((xmlChar *)"");
  4281. ret = xmlDictLookup(ctxt->dict, val, -1);
  4282. xmlFree(val);
  4283. return(ret);
  4284. }
  4285. static const xmlChar *
  4286. xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
  4287. {
  4288. return((const xmlChar*) xmlNodeGetContent(node));
  4289. }
  4290. /**
  4291. * xmlSchemaGetProp:
  4292. * @ctxt: the parser context
  4293. * @node: the node
  4294. * @name: the property name
  4295. *
  4296. * Read a attribute value and internalize the string
  4297. *
  4298. * Returns the string or NULL if not present.
  4299. */
  4300. static const xmlChar *
  4301. xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  4302. const char *name)
  4303. {
  4304. xmlChar *val;
  4305. const xmlChar *ret;
  4306. val = xmlGetNoNsProp(node, BAD_CAST name);
  4307. if (val == NULL)
  4308. return(NULL);
  4309. ret = xmlDictLookup(ctxt->dict, val, -1);
  4310. xmlFree(val);
  4311. return(ret);
  4312. }
  4313. /************************************************************************
  4314. * *
  4315. * Parsing functions *
  4316. * *
  4317. ************************************************************************/
  4318. #define WXS_FIND_GLOBAL_ITEM(slot) \
  4319. if (xmlStrEqual(nsName, schema->targetNamespace)) { \
  4320. ret = xmlHashLookup(schema->slot, name); \
  4321. if (ret != NULL) goto exit; \
  4322. } \
  4323. if (xmlHashSize(schema->schemasImports) > 1) { \
  4324. xmlSchemaImportPtr import; \
  4325. if (nsName == NULL) \
  4326. import = xmlHashLookup(schema->schemasImports, \
  4327. XML_SCHEMAS_NO_NAMESPACE); \
  4328. else \
  4329. import = xmlHashLookup(schema->schemasImports, nsName); \
  4330. if (import == NULL) \
  4331. goto exit; \
  4332. ret = xmlHashLookup(import->schema->slot, name); \
  4333. }
  4334. /**
  4335. * xmlSchemaGetElem:
  4336. * @schema: the schema context
  4337. * @name: the element name
  4338. * @ns: the element namespace
  4339. *
  4340. * Lookup a global element declaration in the schema.
  4341. *
  4342. * Returns the element declaration or NULL if not found.
  4343. */
  4344. static xmlSchemaElementPtr
  4345. xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
  4346. const xmlChar * nsName)
  4347. {
  4348. xmlSchemaElementPtr ret = NULL;
  4349. if ((name == NULL) || (schema == NULL))
  4350. return(NULL);
  4351. if (schema != NULL) {
  4352. WXS_FIND_GLOBAL_ITEM(elemDecl)
  4353. }
  4354. exit:
  4355. #ifdef DEBUG
  4356. if (ret == NULL) {
  4357. if (nsName == NULL)
  4358. fprintf(stderr, "Unable to lookup element decl. %s", name);
  4359. else
  4360. fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
  4361. nsName);
  4362. }
  4363. #endif
  4364. return (ret);
  4365. }
  4366. /**
  4367. * xmlSchemaGetType:
  4368. * @schema: the main schema
  4369. * @name: the type's name
  4370. * nsName: the type's namespace
  4371. *
  4372. * Lookup a type in the schemas or the predefined types
  4373. *
  4374. * Returns the group definition or NULL if not found.
  4375. */
  4376. static xmlSchemaTypePtr
  4377. xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
  4378. const xmlChar * nsName)
  4379. {
  4380. xmlSchemaTypePtr ret = NULL;
  4381. if (name == NULL)
  4382. return (NULL);
  4383. /* First try the built-in types. */
  4384. if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
  4385. ret = xmlSchemaGetPredefinedType(name, nsName);
  4386. if (ret != NULL)
  4387. goto exit;
  4388. /*
  4389. * Note that we try the parsed schemas as well here
  4390. * since one might have parsed the S4S, which contain more
  4391. * than the built-in types.
  4392. * TODO: Can we optimize this?
  4393. */
  4394. }
  4395. if (schema != NULL) {
  4396. WXS_FIND_GLOBAL_ITEM(typeDecl)
  4397. }
  4398. exit:
  4399. #ifdef DEBUG
  4400. if (ret == NULL) {
  4401. if (nsName == NULL)
  4402. fprintf(stderr, "Unable to lookup type %s", name);
  4403. else
  4404. fprintf(stderr, "Unable to lookup type %s:%s", name,
  4405. nsName);
  4406. }
  4407. #endif
  4408. return (ret);
  4409. }
  4410. /**
  4411. * xmlSchemaGetAttributeDecl:
  4412. * @schema: the context of the schema
  4413. * @name: the name of the attribute
  4414. * @ns: the target namespace of the attribute
  4415. *
  4416. * Lookup a an attribute in the schema or imported schemas
  4417. *
  4418. * Returns the attribute declaration or NULL if not found.
  4419. */
  4420. static xmlSchemaAttributePtr
  4421. xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
  4422. const xmlChar * nsName)
  4423. {
  4424. xmlSchemaAttributePtr ret = NULL;
  4425. if ((name == NULL) || (schema == NULL))
  4426. return (NULL);
  4427. if (schema != NULL) {
  4428. WXS_FIND_GLOBAL_ITEM(attrDecl)
  4429. }
  4430. exit:
  4431. #ifdef DEBUG
  4432. if (ret == NULL) {
  4433. if (nsName == NULL)
  4434. fprintf(stderr, "Unable to lookup attribute %s", name);
  4435. else
  4436. fprintf(stderr, "Unable to lookup attribute %s:%s", name,
  4437. nsName);
  4438. }
  4439. #endif
  4440. return (ret);
  4441. }
  4442. /**
  4443. * xmlSchemaGetAttributeGroup:
  4444. * @schema: the context of the schema
  4445. * @name: the name of the attribute group
  4446. * @ns: the target namespace of the attribute group
  4447. *
  4448. * Lookup a an attribute group in the schema or imported schemas
  4449. *
  4450. * Returns the attribute group definition or NULL if not found.
  4451. */
  4452. static xmlSchemaAttributeGroupPtr
  4453. xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
  4454. const xmlChar * nsName)
  4455. {
  4456. xmlSchemaAttributeGroupPtr ret = NULL;
  4457. if ((name == NULL) || (schema == NULL))
  4458. return (NULL);
  4459. if (schema != NULL) {
  4460. WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
  4461. }
  4462. exit:
  4463. /* TODO:
  4464. if ((ret != NULL) && (ret->redef != NULL)) {
  4465. * Return the last redefinition. *
  4466. ret = ret->redef;
  4467. }
  4468. */
  4469. #ifdef DEBUG
  4470. if (ret == NULL) {
  4471. if (nsName == NULL)
  4472. fprintf(stderr, "Unable to lookup attribute group %s", name);
  4473. else
  4474. fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
  4475. nsName);
  4476. }
  4477. #endif
  4478. return (ret);
  4479. }
  4480. /**
  4481. * xmlSchemaGetGroup:
  4482. * @schema: the context of the schema
  4483. * @name: the name of the group
  4484. * @ns: the target namespace of the group
  4485. *
  4486. * Lookup a group in the schema or imported schemas
  4487. *
  4488. * Returns the group definition or NULL if not found.
  4489. */
  4490. static xmlSchemaModelGroupDefPtr
  4491. xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
  4492. const xmlChar * nsName)
  4493. {
  4494. xmlSchemaModelGroupDefPtr ret = NULL;
  4495. if ((name == NULL) || (schema == NULL))
  4496. return (NULL);
  4497. if (schema != NULL) {
  4498. WXS_FIND_GLOBAL_ITEM(groupDecl)
  4499. }
  4500. exit:
  4501. #ifdef DEBUG
  4502. if (ret == NULL) {
  4503. if (nsName == NULL)
  4504. fprintf(stderr, "Unable to lookup group %s", name);
  4505. else
  4506. fprintf(stderr, "Unable to lookup group %s:%s", name,
  4507. nsName);
  4508. }
  4509. #endif
  4510. return (ret);
  4511. }
  4512. static xmlSchemaNotationPtr
  4513. xmlSchemaGetNotation(xmlSchemaPtr schema,
  4514. const xmlChar *name,
  4515. const xmlChar *nsName)
  4516. {
  4517. xmlSchemaNotationPtr ret = NULL;
  4518. if ((name == NULL) || (schema == NULL))
  4519. return (NULL);
  4520. if (schema != NULL) {
  4521. WXS_FIND_GLOBAL_ITEM(notaDecl)
  4522. }
  4523. exit:
  4524. return (ret);
  4525. }
  4526. static xmlSchemaIDCPtr
  4527. xmlSchemaGetIDC(xmlSchemaPtr schema,
  4528. const xmlChar *name,
  4529. const xmlChar *nsName)
  4530. {
  4531. xmlSchemaIDCPtr ret = NULL;
  4532. if ((name == NULL) || (schema == NULL))
  4533. return (NULL);
  4534. if (schema != NULL) {
  4535. WXS_FIND_GLOBAL_ITEM(idcDef)
  4536. }
  4537. exit:
  4538. return (ret);
  4539. }
  4540. /**
  4541. * xmlSchemaGetNamedComponent:
  4542. * @schema: the schema
  4543. * @name: the name of the group
  4544. * @ns: the target namespace of the group
  4545. *
  4546. * Lookup a group in the schema or imported schemas
  4547. *
  4548. * Returns the group definition or NULL if not found.
  4549. */
  4550. static xmlSchemaBasicItemPtr
  4551. xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
  4552. xmlSchemaTypeType itemType,
  4553. const xmlChar *name,
  4554. const xmlChar *targetNs)
  4555. {
  4556. switch (itemType) {
  4557. case XML_SCHEMA_TYPE_GROUP:
  4558. return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
  4559. name, targetNs));
  4560. case XML_SCHEMA_TYPE_ELEMENT:
  4561. return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
  4562. name, targetNs));
  4563. default:
  4564. TODO
  4565. return (NULL);
  4566. }
  4567. }
  4568. /************************************************************************
  4569. * *
  4570. * Parsing functions *
  4571. * *
  4572. ************************************************************************/
  4573. #define IS_BLANK_NODE(n) \
  4574. (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
  4575. /**
  4576. * xmlSchemaIsBlank:
  4577. * @str: a string
  4578. * @len: the length of the string or -1
  4579. *
  4580. * Check if a string is ignorable
  4581. *
  4582. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  4583. */
  4584. static int
  4585. xmlSchemaIsBlank(xmlChar * str, int len)
  4586. {
  4587. if (str == NULL)
  4588. return (1);
  4589. if (len < 0) {
  4590. while (*str != 0) {
  4591. if (!(IS_BLANK_CH(*str)))
  4592. return (0);
  4593. str++;
  4594. }
  4595. } else while ((*str != 0) && (len != 0)) {
  4596. if (!(IS_BLANK_CH(*str)))
  4597. return (0);
  4598. str++;
  4599. len--;
  4600. }
  4601. return (1);
  4602. }
  4603. #define WXS_COMP_NAME(c, t) ((t) (c))->name
  4604. #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
  4605. /*
  4606. * xmlSchemaFindRedefCompInGraph:
  4607. * ATTENTION TODO: This uses pointer comp. for strings.
  4608. */
  4609. static xmlSchemaBasicItemPtr
  4610. xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
  4611. xmlSchemaTypeType type,
  4612. const xmlChar *name,
  4613. const xmlChar *nsName)
  4614. {
  4615. xmlSchemaBasicItemPtr ret;
  4616. int i;
  4617. if ((bucket == NULL) || (name == NULL))
  4618. return(NULL);
  4619. if ((bucket->globals == NULL) ||
  4620. (bucket->globals->nbItems == 0))
  4621. goto subschemas;
  4622. /*
  4623. * Search in global components.
  4624. */
  4625. for (i = 0; i < bucket->globals->nbItems; i++) {
  4626. ret = bucket->globals->items[i];
  4627. if (ret->type == type) {
  4628. switch (type) {
  4629. case XML_SCHEMA_TYPE_COMPLEX:
  4630. case XML_SCHEMA_TYPE_SIMPLE:
  4631. if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
  4632. (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
  4633. nsName))
  4634. {
  4635. return(ret);
  4636. }
  4637. break;
  4638. case XML_SCHEMA_TYPE_GROUP:
  4639. if ((WXS_COMP_NAME(ret,
  4640. xmlSchemaModelGroupDefPtr) == name) &&
  4641. (WXS_COMP_TNS(ret,
  4642. xmlSchemaModelGroupDefPtr) == nsName))
  4643. {
  4644. return(ret);
  4645. }
  4646. break;
  4647. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  4648. if ((WXS_COMP_NAME(ret,
  4649. xmlSchemaAttributeGroupPtr) == name) &&
  4650. (WXS_COMP_TNS(ret,
  4651. xmlSchemaAttributeGroupPtr) == nsName))
  4652. {
  4653. return(ret);
  4654. }
  4655. break;
  4656. default:
  4657. /* Should not be hit. */
  4658. return(NULL);
  4659. }
  4660. }
  4661. }
  4662. subschemas:
  4663. /*
  4664. * Process imported/included schemas.
  4665. */
  4666. if (bucket->relations != NULL) {
  4667. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  4668. /*
  4669. * TODO: Marking the bucket will not avoid multiple searches
  4670. * in the same schema, but avoids at least circularity.
  4671. */
  4672. bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
  4673. do {
  4674. if ((rel->bucket != NULL) &&
  4675. ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
  4676. ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
  4677. type, name, nsName);
  4678. if (ret != NULL)
  4679. return(ret);
  4680. }
  4681. rel = rel->next;
  4682. } while (rel != NULL);
  4683. bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
  4684. }
  4685. return(NULL);
  4686. }
  4687. /**
  4688. * xmlSchemaAddNotation:
  4689. * @ctxt: a schema parser context
  4690. * @schema: the schema being built
  4691. * @name: the item name
  4692. *
  4693. * Add an XML schema annotation declaration
  4694. * *WARNING* this interface is highly subject to change
  4695. *
  4696. * Returns the new struture or NULL in case of error
  4697. */
  4698. static xmlSchemaNotationPtr
  4699. xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4700. const xmlChar *name, const xmlChar *nsName,
  4701. xmlNodePtr node ATTRIBUTE_UNUSED)
  4702. {
  4703. xmlSchemaNotationPtr ret = NULL;
  4704. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  4705. return (NULL);
  4706. ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
  4707. if (ret == NULL) {
  4708. xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
  4709. return (NULL);
  4710. }
  4711. memset(ret, 0, sizeof(xmlSchemaNotation));
  4712. ret->type = XML_SCHEMA_TYPE_NOTATION;
  4713. ret->name = name;
  4714. ret->targetNamespace = nsName;
  4715. /* TODO: do we need the node to be set?
  4716. * ret->node = node;*/
  4717. WXS_ADD_GLOBAL(ctxt, ret);
  4718. return (ret);
  4719. }
  4720. /**
  4721. * xmlSchemaAddAttribute:
  4722. * @ctxt: a schema parser context
  4723. * @schema: the schema being built
  4724. * @name: the item name
  4725. * @namespace: the namespace
  4726. *
  4727. * Add an XML schema Attrribute declaration
  4728. * *WARNING* this interface is highly subject to change
  4729. *
  4730. * Returns the new struture or NULL in case of error
  4731. */
  4732. static xmlSchemaAttributePtr
  4733. xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4734. const xmlChar * name, const xmlChar * nsName,
  4735. xmlNodePtr node, int topLevel)
  4736. {
  4737. xmlSchemaAttributePtr ret = NULL;
  4738. if ((ctxt == NULL) || (schema == NULL))
  4739. return (NULL);
  4740. ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
  4741. if (ret == NULL) {
  4742. xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
  4743. return (NULL);
  4744. }
  4745. memset(ret, 0, sizeof(xmlSchemaAttribute));
  4746. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
  4747. ret->node = node;
  4748. ret->name = name;
  4749. ret->targetNamespace = nsName;
  4750. if (topLevel)
  4751. WXS_ADD_GLOBAL(ctxt, ret);
  4752. else
  4753. WXS_ADD_LOCAL(ctxt, ret);
  4754. WXS_ADD_PENDING(ctxt, ret);
  4755. return (ret);
  4756. }
  4757. /**
  4758. * xmlSchemaAddAttributeUse:
  4759. * @ctxt: a schema parser context
  4760. * @schema: the schema being built
  4761. * @name: the item name
  4762. * @namespace: the namespace
  4763. *
  4764. * Add an XML schema Attrribute declaration
  4765. * *WARNING* this interface is highly subject to change
  4766. *
  4767. * Returns the new struture or NULL in case of error
  4768. */
  4769. static xmlSchemaAttributeUsePtr
  4770. xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
  4771. xmlNodePtr node)
  4772. {
  4773. xmlSchemaAttributeUsePtr ret = NULL;
  4774. if (pctxt == NULL)
  4775. return (NULL);
  4776. ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
  4777. if (ret == NULL) {
  4778. xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
  4779. return (NULL);
  4780. }
  4781. memset(ret, 0, sizeof(xmlSchemaAttributeUse));
  4782. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
  4783. ret->node = node;
  4784. WXS_ADD_LOCAL(pctxt, ret);
  4785. return (ret);
  4786. }
  4787. /*
  4788. * xmlSchemaAddRedef:
  4789. *
  4790. * Adds a redefinition information. This is used at a later stage to:
  4791. * resolve references to the redefined components and to check constraints.
  4792. */
  4793. static xmlSchemaRedefPtr
  4794. xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
  4795. xmlSchemaBucketPtr targetBucket,
  4796. void *item,
  4797. const xmlChar *refName,
  4798. const xmlChar *refTargetNs)
  4799. {
  4800. xmlSchemaRedefPtr ret;
  4801. ret = (xmlSchemaRedefPtr)
  4802. xmlMalloc(sizeof(xmlSchemaRedef));
  4803. if (ret == NULL) {
  4804. xmlSchemaPErrMemory(pctxt,
  4805. "allocating redefinition info", NULL);
  4806. return (NULL);
  4807. }
  4808. memset(ret, 0, sizeof(xmlSchemaRedef));
  4809. ret->item = item;
  4810. ret->targetBucket = targetBucket;
  4811. ret->refName = refName;
  4812. ret->refTargetNs = refTargetNs;
  4813. if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
  4814. WXS_CONSTRUCTOR(pctxt)->redefs = ret;
  4815. else
  4816. WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
  4817. WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
  4818. return (ret);
  4819. }
  4820. /**
  4821. * xmlSchemaAddAttributeGroupDefinition:
  4822. * @ctxt: a schema parser context
  4823. * @schema: the schema being built
  4824. * @name: the item name
  4825. * @nsName: the target namespace
  4826. * @node: the corresponding node
  4827. *
  4828. * Add an XML schema Attrribute Group definition.
  4829. *
  4830. * Returns the new struture or NULL in case of error
  4831. */
  4832. static xmlSchemaAttributeGroupPtr
  4833. xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  4834. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  4835. const xmlChar *name,
  4836. const xmlChar *nsName,
  4837. xmlNodePtr node)
  4838. {
  4839. xmlSchemaAttributeGroupPtr ret = NULL;
  4840. if ((pctxt == NULL) || (name == NULL))
  4841. return (NULL);
  4842. ret = (xmlSchemaAttributeGroupPtr)
  4843. xmlMalloc(sizeof(xmlSchemaAttributeGroup));
  4844. if (ret == NULL) {
  4845. xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
  4846. return (NULL);
  4847. }
  4848. memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
  4849. ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
  4850. ret->name = name;
  4851. ret->targetNamespace = nsName;
  4852. ret->node = node;
  4853. /* TODO: Remove the flag. */
  4854. ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
  4855. if (pctxt->isRedefine) {
  4856. pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
  4857. ret, name, nsName);
  4858. if (pctxt->redef == NULL) {
  4859. xmlFree(ret);
  4860. return(NULL);
  4861. }
  4862. pctxt->redefCounter = 0;
  4863. }
  4864. WXS_ADD_GLOBAL(pctxt, ret);
  4865. WXS_ADD_PENDING(pctxt, ret);
  4866. return (ret);
  4867. }
  4868. /**
  4869. * xmlSchemaAddElement:
  4870. * @ctxt: a schema parser context
  4871. * @schema: the schema being built
  4872. * @name: the type name
  4873. * @namespace: the type namespace
  4874. *
  4875. * Add an XML schema Element declaration
  4876. * *WARNING* this interface is highly subject to change
  4877. *
  4878. * Returns the new struture or NULL in case of error
  4879. */
  4880. static xmlSchemaElementPtr
  4881. xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
  4882. const xmlChar * name, const xmlChar * nsName,
  4883. xmlNodePtr node, int topLevel)
  4884. {
  4885. xmlSchemaElementPtr ret = NULL;
  4886. if ((ctxt == NULL) || (name == NULL))
  4887. return (NULL);
  4888. ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
  4889. if (ret == NULL) {
  4890. xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
  4891. return (NULL);
  4892. }
  4893. memset(ret, 0, sizeof(xmlSchemaElement));
  4894. ret->type = XML_SCHEMA_TYPE_ELEMENT;
  4895. ret->name = name;
  4896. ret->targetNamespace = nsName;
  4897. ret->node = node;
  4898. if (topLevel)
  4899. WXS_ADD_GLOBAL(ctxt, ret);
  4900. else
  4901. WXS_ADD_LOCAL(ctxt, ret);
  4902. WXS_ADD_PENDING(ctxt, ret);
  4903. return (ret);
  4904. }
  4905. /**
  4906. * xmlSchemaAddType:
  4907. * @ctxt: a schema parser context
  4908. * @schema: the schema being built
  4909. * @name: the item name
  4910. * @namespace: the namespace
  4911. *
  4912. * Add an XML schema item
  4913. * *WARNING* this interface is highly subject to change
  4914. *
  4915. * Returns the new struture or NULL in case of error
  4916. */
  4917. static xmlSchemaTypePtr
  4918. xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4919. xmlSchemaTypeType type,
  4920. const xmlChar * name, const xmlChar * nsName,
  4921. xmlNodePtr node, int topLevel)
  4922. {
  4923. xmlSchemaTypePtr ret = NULL;
  4924. if ((ctxt == NULL) || (schema == NULL))
  4925. return (NULL);
  4926. ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
  4927. if (ret == NULL) {
  4928. xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
  4929. return (NULL);
  4930. }
  4931. memset(ret, 0, sizeof(xmlSchemaType));
  4932. ret->type = type;
  4933. ret->name = name;
  4934. ret->targetNamespace = nsName;
  4935. ret->node = node;
  4936. if (topLevel) {
  4937. if (ctxt->isRedefine) {
  4938. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  4939. ret, name, nsName);
  4940. if (ctxt->redef == NULL) {
  4941. xmlFree(ret);
  4942. return(NULL);
  4943. }
  4944. ctxt->redefCounter = 0;
  4945. }
  4946. WXS_ADD_GLOBAL(ctxt, ret);
  4947. } else
  4948. WXS_ADD_LOCAL(ctxt, ret);
  4949. WXS_ADD_PENDING(ctxt, ret);
  4950. return (ret);
  4951. }
  4952. static xmlSchemaQNameRefPtr
  4953. xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
  4954. xmlSchemaTypeType refType,
  4955. const xmlChar *refName,
  4956. const xmlChar *refNs)
  4957. {
  4958. xmlSchemaQNameRefPtr ret;
  4959. ret = (xmlSchemaQNameRefPtr)
  4960. xmlMalloc(sizeof(xmlSchemaQNameRef));
  4961. if (ret == NULL) {
  4962. xmlSchemaPErrMemory(pctxt,
  4963. "allocating QName reference item", NULL);
  4964. return (NULL);
  4965. }
  4966. ret->node = NULL;
  4967. ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
  4968. ret->name = refName;
  4969. ret->targetNamespace = refNs;
  4970. ret->item = NULL;
  4971. ret->itemType = refType;
  4972. /*
  4973. * Store the reference item in the schema.
  4974. */
  4975. WXS_ADD_LOCAL(pctxt, ret);
  4976. return (ret);
  4977. }
  4978. static xmlSchemaAttributeUseProhibPtr
  4979. xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
  4980. {
  4981. xmlSchemaAttributeUseProhibPtr ret;
  4982. ret = (xmlSchemaAttributeUseProhibPtr)
  4983. xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
  4984. if (ret == NULL) {
  4985. xmlSchemaPErrMemory(pctxt,
  4986. "allocating attribute use prohibition", NULL);
  4987. return (NULL);
  4988. }
  4989. memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
  4990. ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
  4991. WXS_ADD_LOCAL(pctxt, ret);
  4992. return (ret);
  4993. }
  4994. /**
  4995. * xmlSchemaAddModelGroup:
  4996. * @ctxt: a schema parser context
  4997. * @schema: the schema being built
  4998. * @type: the "compositor" type of the model group
  4999. * @node: the node in the schema doc
  5000. *
  5001. * Adds a schema model group
  5002. * *WARNING* this interface is highly subject to change
  5003. *
  5004. * Returns the new struture or NULL in case of error
  5005. */
  5006. static xmlSchemaModelGroupPtr
  5007. xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
  5008. xmlSchemaPtr schema,
  5009. xmlSchemaTypeType type,
  5010. xmlNodePtr node)
  5011. {
  5012. xmlSchemaModelGroupPtr ret = NULL;
  5013. if ((ctxt == NULL) || (schema == NULL))
  5014. return (NULL);
  5015. ret = (xmlSchemaModelGroupPtr)
  5016. xmlMalloc(sizeof(xmlSchemaModelGroup));
  5017. if (ret == NULL) {
  5018. xmlSchemaPErrMemory(ctxt, "allocating model group component",
  5019. NULL);
  5020. return (NULL);
  5021. }
  5022. memset(ret, 0, sizeof(xmlSchemaModelGroup));
  5023. ret->type = type;
  5024. ret->node = node;
  5025. WXS_ADD_LOCAL(ctxt, ret);
  5026. if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
  5027. (type == XML_SCHEMA_TYPE_CHOICE))
  5028. WXS_ADD_PENDING(ctxt, ret);
  5029. return (ret);
  5030. }
  5031. /**
  5032. * xmlSchemaAddParticle:
  5033. * @ctxt: a schema parser context
  5034. * @schema: the schema being built
  5035. * @node: the corresponding node in the schema doc
  5036. * @min: the minOccurs
  5037. * @max: the maxOccurs
  5038. *
  5039. * Adds an XML schema particle component.
  5040. * *WARNING* this interface is highly subject to change
  5041. *
  5042. * Returns the new struture or NULL in case of error
  5043. */
  5044. static xmlSchemaParticlePtr
  5045. xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
  5046. xmlNodePtr node, int min, int max)
  5047. {
  5048. xmlSchemaParticlePtr ret = NULL;
  5049. if (ctxt == NULL)
  5050. return (NULL);
  5051. #ifdef DEBUG
  5052. fprintf(stderr, "Adding particle component\n");
  5053. #endif
  5054. ret = (xmlSchemaParticlePtr)
  5055. xmlMalloc(sizeof(xmlSchemaParticle));
  5056. if (ret == NULL) {
  5057. xmlSchemaPErrMemory(ctxt, "allocating particle component",
  5058. NULL);
  5059. return (NULL);
  5060. }
  5061. ret->type = XML_SCHEMA_TYPE_PARTICLE;
  5062. ret->annot = NULL;
  5063. ret->node = node;
  5064. ret->minOccurs = min;
  5065. ret->maxOccurs = max;
  5066. ret->next = NULL;
  5067. ret->children = NULL;
  5068. WXS_ADD_LOCAL(ctxt, ret);
  5069. /*
  5070. * Note that addition to pending components will be done locally
  5071. * to the specific parsing function, since the most particles
  5072. * need not to be fixed up (i.e. the reference to be resolved).
  5073. * REMOVED: WXS_ADD_PENDING(ctxt, ret);
  5074. */
  5075. return (ret);
  5076. }
  5077. /**
  5078. * xmlSchemaAddModelGroupDefinition:
  5079. * @ctxt: a schema validation context
  5080. * @schema: the schema being built
  5081. * @name: the group name
  5082. *
  5083. * Add an XML schema Group definition
  5084. *
  5085. * Returns the new struture or NULL in case of error
  5086. */
  5087. static xmlSchemaModelGroupDefPtr
  5088. xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  5089. xmlSchemaPtr schema,
  5090. const xmlChar *name,
  5091. const xmlChar *nsName,
  5092. xmlNodePtr node)
  5093. {
  5094. xmlSchemaModelGroupDefPtr ret = NULL;
  5095. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5096. return (NULL);
  5097. ret = (xmlSchemaModelGroupDefPtr)
  5098. xmlMalloc(sizeof(xmlSchemaModelGroupDef));
  5099. if (ret == NULL) {
  5100. xmlSchemaPErrMemory(ctxt, "adding group", NULL);
  5101. return (NULL);
  5102. }
  5103. memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
  5104. ret->name = name;
  5105. ret->type = XML_SCHEMA_TYPE_GROUP;
  5106. ret->node = node;
  5107. ret->targetNamespace = nsName;
  5108. if (ctxt->isRedefine) {
  5109. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5110. ret, name, nsName);
  5111. if (ctxt->redef == NULL) {
  5112. xmlFree(ret);
  5113. return(NULL);
  5114. }
  5115. ctxt->redefCounter = 0;
  5116. }
  5117. WXS_ADD_GLOBAL(ctxt, ret);
  5118. WXS_ADD_PENDING(ctxt, ret);
  5119. return (ret);
  5120. }
  5121. /**
  5122. * xmlSchemaNewWildcardNs:
  5123. * @ctxt: a schema validation context
  5124. *
  5125. * Creates a new wildcard namespace constraint.
  5126. *
  5127. * Returns the new struture or NULL in case of error
  5128. */
  5129. static xmlSchemaWildcardNsPtr
  5130. xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
  5131. {
  5132. xmlSchemaWildcardNsPtr ret;
  5133. ret = (xmlSchemaWildcardNsPtr)
  5134. xmlMalloc(sizeof(xmlSchemaWildcardNs));
  5135. if (ret == NULL) {
  5136. xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
  5137. return (NULL);
  5138. }
  5139. ret->value = NULL;
  5140. ret->next = NULL;
  5141. return (ret);
  5142. }
  5143. static xmlSchemaIDCPtr
  5144. xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5145. const xmlChar *name, const xmlChar *nsName,
  5146. int category, xmlNodePtr node)
  5147. {
  5148. xmlSchemaIDCPtr ret = NULL;
  5149. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5150. return (NULL);
  5151. ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
  5152. if (ret == NULL) {
  5153. xmlSchemaPErrMemory(ctxt,
  5154. "allocating an identity-constraint definition", NULL);
  5155. return (NULL);
  5156. }
  5157. memset(ret, 0, sizeof(xmlSchemaIDC));
  5158. /* The target namespace of the parent element declaration. */
  5159. ret->targetNamespace = nsName;
  5160. ret->name = name;
  5161. ret->type = category;
  5162. ret->node = node;
  5163. WXS_ADD_GLOBAL(ctxt, ret);
  5164. /*
  5165. * Only keyrefs need to be fixup up.
  5166. */
  5167. if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
  5168. WXS_ADD_PENDING(ctxt, ret);
  5169. return (ret);
  5170. }
  5171. /**
  5172. * xmlSchemaAddWildcard:
  5173. * @ctxt: a schema validation context
  5174. * @schema: a schema
  5175. *
  5176. * Adds a wildcard.
  5177. * It corresponds to a xsd:anyAttribute and xsd:any.
  5178. *
  5179. * Returns the new struture or NULL in case of error
  5180. */
  5181. static xmlSchemaWildcardPtr
  5182. xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5183. xmlSchemaTypeType type, xmlNodePtr node)
  5184. {
  5185. xmlSchemaWildcardPtr ret = NULL;
  5186. if ((ctxt == NULL) || (schema == NULL))
  5187. return (NULL);
  5188. ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
  5189. if (ret == NULL) {
  5190. xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
  5191. return (NULL);
  5192. }
  5193. memset(ret, 0, sizeof(xmlSchemaWildcard));
  5194. ret->type = type;
  5195. ret->node = node;
  5196. WXS_ADD_LOCAL(ctxt, ret);
  5197. return (ret);
  5198. }
  5199. static void
  5200. xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
  5201. {
  5202. if (group == NULL)
  5203. return;
  5204. if (group->members != NULL)
  5205. xmlSchemaItemListFree(group->members);
  5206. xmlFree(group);
  5207. }
  5208. static xmlSchemaSubstGroupPtr
  5209. xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
  5210. xmlSchemaElementPtr head)
  5211. {
  5212. xmlSchemaSubstGroupPtr ret;
  5213. /* Init subst group hash. */
  5214. if (WXS_SUBST_GROUPS(pctxt) == NULL) {
  5215. WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
  5216. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5217. return(NULL);
  5218. }
  5219. /* Create a new substitution group. */
  5220. ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
  5221. if (ret == NULL) {
  5222. xmlSchemaPErrMemory(NULL,
  5223. "allocating a substitution group container", NULL);
  5224. return(NULL);
  5225. }
  5226. memset(ret, 0, sizeof(xmlSchemaSubstGroup));
  5227. ret->head = head;
  5228. /* Create list of members. */
  5229. ret->members = xmlSchemaItemListCreate();
  5230. if (ret->members == NULL) {
  5231. xmlSchemaSubstGroupFree(ret);
  5232. return(NULL);
  5233. }
  5234. /* Add subst group to hash. */
  5235. if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
  5236. head->name, head->targetNamespace, ret) != 0) {
  5237. PERROR_INT("xmlSchemaSubstGroupAdd",
  5238. "failed to add a new substitution container");
  5239. xmlSchemaSubstGroupFree(ret);
  5240. return(NULL);
  5241. }
  5242. return(ret);
  5243. }
  5244. static xmlSchemaSubstGroupPtr
  5245. xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
  5246. xmlSchemaElementPtr head)
  5247. {
  5248. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5249. return(NULL);
  5250. return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
  5251. head->name, head->targetNamespace));
  5252. }
  5253. /**
  5254. * xmlSchemaAddElementSubstitutionMember:
  5255. * @pctxt: a schema parser context
  5256. * @head: the head of the substitution group
  5257. * @member: the new member of the substitution group
  5258. *
  5259. * Allocate a new annotation structure.
  5260. *
  5261. * Returns the newly allocated structure or NULL in case or error
  5262. */
  5263. static int
  5264. xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
  5265. xmlSchemaElementPtr head,
  5266. xmlSchemaElementPtr member)
  5267. {
  5268. xmlSchemaSubstGroupPtr substGroup = NULL;
  5269. if ((pctxt == NULL) || (head == NULL) || (member == NULL))
  5270. return (-1);
  5271. substGroup = xmlSchemaSubstGroupGet(pctxt, head);
  5272. if (substGroup == NULL)
  5273. substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
  5274. if (substGroup == NULL)
  5275. return(-1);
  5276. if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
  5277. return(-1);
  5278. return(0);
  5279. }
  5280. /************************************************************************
  5281. * *
  5282. * Utilities for parsing *
  5283. * *
  5284. ************************************************************************/
  5285. /**
  5286. * xmlSchemaPValAttrNodeQNameValue:
  5287. * @ctxt: a schema parser context
  5288. * @schema: the schema context
  5289. * @ownerDes: the designation of the parent element
  5290. * @ownerItem: the parent as a schema object
  5291. * @value: the QName value
  5292. * @local: the resulting local part if found, the attribute value otherwise
  5293. * @uri: the resulting namespace URI if found
  5294. *
  5295. * Extracts the local name and the URI of a QName value and validates it.
  5296. * This one is intended to be used on attribute values that
  5297. * should resolve to schema components.
  5298. *
  5299. * Returns 0, in case the QName is valid, a positive error code
  5300. * if not valid and -1 if an internal error occurs.
  5301. */
  5302. static int
  5303. xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
  5304. xmlSchemaPtr schema,
  5305. xmlSchemaBasicItemPtr ownerItem,
  5306. xmlAttrPtr attr,
  5307. const xmlChar *value,
  5308. const xmlChar **uri,
  5309. const xmlChar **local)
  5310. {
  5311. const xmlChar *pref;
  5312. xmlNsPtr ns;
  5313. int len, ret;
  5314. *uri = NULL;
  5315. *local = NULL;
  5316. ret = xmlValidateQName(value, 1);
  5317. if (ret > 0) {
  5318. xmlSchemaPSimpleTypeErr(ctxt,
  5319. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5320. ownerItem, (xmlNodePtr) attr,
  5321. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  5322. NULL, value, NULL, NULL, NULL);
  5323. *local = value;
  5324. return (ctxt->err);
  5325. } else if (ret < 0)
  5326. return (-1);
  5327. if (!strchr((char *) value, ':')) {
  5328. ns = xmlSearchNs(attr->doc, attr->parent, NULL);
  5329. if (ns)
  5330. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5331. else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
  5332. /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
  5333. * parser context. */
  5334. /*
  5335. * This one takes care of included schemas with no
  5336. * target namespace.
  5337. */
  5338. *uri = ctxt->targetNamespace;
  5339. }
  5340. *local = xmlDictLookup(ctxt->dict, value, -1);
  5341. return (0);
  5342. }
  5343. /*
  5344. * At this point xmlSplitQName3 has to return a local name.
  5345. */
  5346. *local = xmlSplitQName3(value, &len);
  5347. *local = xmlDictLookup(ctxt->dict, *local, -1);
  5348. pref = xmlDictLookup(ctxt->dict, value, len);
  5349. ns = xmlSearchNs(attr->doc, attr->parent, pref);
  5350. if (ns == NULL) {
  5351. xmlSchemaPSimpleTypeErr(ctxt,
  5352. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5353. ownerItem, (xmlNodePtr) attr,
  5354. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
  5355. "The value '%s' of simple type 'xs:QName' has no "
  5356. "corresponding namespace declaration in scope", value, NULL);
  5357. return (ctxt->err);
  5358. } else {
  5359. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5360. }
  5361. return (0);
  5362. }
  5363. /**
  5364. * xmlSchemaPValAttrNodeQName:
  5365. * @ctxt: a schema parser context
  5366. * @schema: the schema context
  5367. * @ownerDes: the designation of the owner element
  5368. * @ownerItem: the owner as a schema object
  5369. * @attr: the attribute node
  5370. * @local: the resulting local part if found, the attribute value otherwise
  5371. * @uri: the resulting namespace URI if found
  5372. *
  5373. * Extracts and validates the QName of an attribute value.
  5374. * This one is intended to be used on attribute values that
  5375. * should resolve to schema components.
  5376. *
  5377. * Returns 0, in case the QName is valid, a positive error code
  5378. * if not valid and -1 if an internal error occurs.
  5379. */
  5380. static int
  5381. xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
  5382. xmlSchemaPtr schema,
  5383. xmlSchemaBasicItemPtr ownerItem,
  5384. xmlAttrPtr attr,
  5385. const xmlChar **uri,
  5386. const xmlChar **local)
  5387. {
  5388. const xmlChar *value;
  5389. value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5390. return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  5391. ownerItem, attr, value, uri, local));
  5392. }
  5393. /**
  5394. * xmlSchemaPValAttrQName:
  5395. * @ctxt: a schema parser context
  5396. * @schema: the schema context
  5397. * @ownerDes: the designation of the parent element
  5398. * @ownerItem: the owner as a schema object
  5399. * @ownerElem: the parent node of the attribute
  5400. * @name: the name of the attribute
  5401. * @local: the resulting local part if found, the attribute value otherwise
  5402. * @uri: the resulting namespace URI if found
  5403. *
  5404. * Extracts and validates the QName of an attribute value.
  5405. *
  5406. * Returns 0, in case the QName is valid, a positive error code
  5407. * if not valid and -1 if an internal error occurs.
  5408. */
  5409. static int
  5410. xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
  5411. xmlSchemaPtr schema,
  5412. xmlSchemaBasicItemPtr ownerItem,
  5413. xmlNodePtr ownerElem,
  5414. const char *name,
  5415. const xmlChar **uri,
  5416. const xmlChar **local)
  5417. {
  5418. xmlAttrPtr attr;
  5419. attr = xmlSchemaGetPropNode(ownerElem, name);
  5420. if (attr == NULL) {
  5421. *local = NULL;
  5422. *uri = NULL;
  5423. return (0);
  5424. }
  5425. return (xmlSchemaPValAttrNodeQName(ctxt, schema,
  5426. ownerItem, attr, uri, local));
  5427. }
  5428. /**
  5429. * xmlSchemaPValAttrID:
  5430. * @ctxt: a schema parser context
  5431. * @schema: the schema context
  5432. * @ownerDes: the designation of the parent element
  5433. * @ownerItem: the owner as a schema object
  5434. * @ownerElem: the parent node of the attribute
  5435. * @name: the name of the attribute
  5436. *
  5437. * Extracts and validates the ID of an attribute value.
  5438. *
  5439. * Returns 0, in case the ID is valid, a positive error code
  5440. * if not valid and -1 if an internal error occurs.
  5441. */
  5442. static int
  5443. xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
  5444. {
  5445. int ret;
  5446. const xmlChar *value;
  5447. if (attr == NULL)
  5448. return(0);
  5449. value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
  5450. ret = xmlValidateNCName(value, 1);
  5451. if (ret == 0) {
  5452. /*
  5453. * NOTE: the IDness might have already be declared in the DTD
  5454. */
  5455. if (attr->atype != XML_ATTRIBUTE_ID) {
  5456. xmlIDPtr res;
  5457. xmlChar *strip;
  5458. /*
  5459. * TODO: Use xmlSchemaStrip here; it's not exported at this
  5460. * moment.
  5461. */
  5462. strip = xmlSchemaCollapseString(value);
  5463. if (strip != NULL) {
  5464. xmlFree((xmlChar *) value);
  5465. value = strip;
  5466. }
  5467. res = xmlAddID(NULL, attr->doc, value, attr);
  5468. if (res == NULL) {
  5469. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5470. xmlSchemaPSimpleTypeErr(ctxt,
  5471. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5472. NULL, (xmlNodePtr) attr,
  5473. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5474. NULL, NULL, "Duplicate value '%s' of simple "
  5475. "type 'xs:ID'", value, NULL);
  5476. } else
  5477. attr->atype = XML_ATTRIBUTE_ID;
  5478. }
  5479. } else if (ret > 0) {
  5480. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5481. xmlSchemaPSimpleTypeErr(ctxt,
  5482. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5483. NULL, (xmlNodePtr) attr,
  5484. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5485. NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
  5486. "not a valid 'xs:NCName'",
  5487. value, NULL);
  5488. }
  5489. if (value != NULL)
  5490. xmlFree((xmlChar *)value);
  5491. return (ret);
  5492. }
  5493. static int
  5494. xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
  5495. xmlNodePtr ownerElem,
  5496. const xmlChar *name)
  5497. {
  5498. xmlAttrPtr attr;
  5499. attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
  5500. if (attr == NULL)
  5501. return(0);
  5502. return(xmlSchemaPValAttrNodeID(ctxt, attr));
  5503. }
  5504. /**
  5505. * xmlGetMaxOccurs:
  5506. * @ctxt: a schema validation context
  5507. * @node: a subtree containing XML Schema informations
  5508. *
  5509. * Get the maxOccurs property
  5510. *
  5511. * Returns the default if not found, or the value
  5512. */
  5513. static int
  5514. xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5515. int min, int max, int def, const char *expected)
  5516. {
  5517. const xmlChar *val, *cur;
  5518. int ret = 0;
  5519. xmlAttrPtr attr;
  5520. attr = xmlSchemaGetPropNode(node, "maxOccurs");
  5521. if (attr == NULL)
  5522. return (def);
  5523. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5524. if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
  5525. if (max != UNBOUNDED) {
  5526. xmlSchemaPSimpleTypeErr(ctxt,
  5527. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5528. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5529. NULL, (xmlNodePtr) attr, NULL, expected,
  5530. val, NULL, NULL, NULL);
  5531. return (def);
  5532. } else
  5533. return (UNBOUNDED); /* encoding it with -1 might be another option */
  5534. }
  5535. cur = val;
  5536. while (IS_BLANK_CH(*cur))
  5537. cur++;
  5538. if (*cur == 0) {
  5539. xmlSchemaPSimpleTypeErr(ctxt,
  5540. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5541. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5542. NULL, (xmlNodePtr) attr, NULL, expected,
  5543. val, NULL, NULL, NULL);
  5544. return (def);
  5545. }
  5546. while ((*cur >= '0') && (*cur <= '9')) {
  5547. ret = ret * 10 + (*cur - '0');
  5548. cur++;
  5549. }
  5550. while (IS_BLANK_CH(*cur))
  5551. cur++;
  5552. /*
  5553. * TODO: Restrict the maximal value to Integer.
  5554. */
  5555. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5556. xmlSchemaPSimpleTypeErr(ctxt,
  5557. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5558. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5559. NULL, (xmlNodePtr) attr, NULL, expected,
  5560. val, NULL, NULL, NULL);
  5561. return (def);
  5562. }
  5563. return (ret);
  5564. }
  5565. /**
  5566. * xmlGetMinOccurs:
  5567. * @ctxt: a schema validation context
  5568. * @node: a subtree containing XML Schema informations
  5569. *
  5570. * Get the minOccurs property
  5571. *
  5572. * Returns the default if not found, or the value
  5573. */
  5574. static int
  5575. xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5576. int min, int max, int def, const char *expected)
  5577. {
  5578. const xmlChar *val, *cur;
  5579. int ret = 0;
  5580. xmlAttrPtr attr;
  5581. attr = xmlSchemaGetPropNode(node, "minOccurs");
  5582. if (attr == NULL)
  5583. return (def);
  5584. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5585. cur = val;
  5586. while (IS_BLANK_CH(*cur))
  5587. cur++;
  5588. if (*cur == 0) {
  5589. xmlSchemaPSimpleTypeErr(ctxt,
  5590. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5591. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5592. NULL, (xmlNodePtr) attr, NULL, expected,
  5593. val, NULL, NULL, NULL);
  5594. return (def);
  5595. }
  5596. while ((*cur >= '0') && (*cur <= '9')) {
  5597. ret = ret * 10 + (*cur - '0');
  5598. cur++;
  5599. }
  5600. while (IS_BLANK_CH(*cur))
  5601. cur++;
  5602. /*
  5603. * TODO: Restrict the maximal value to Integer.
  5604. */
  5605. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5606. xmlSchemaPSimpleTypeErr(ctxt,
  5607. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5608. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5609. NULL, (xmlNodePtr) attr, NULL, expected,
  5610. val, NULL, NULL, NULL);
  5611. return (def);
  5612. }
  5613. return (ret);
  5614. }
  5615. /**
  5616. * xmlSchemaPGetBoolNodeValue:
  5617. * @ctxt: a schema validation context
  5618. * @ownerDes: owner designation
  5619. * @ownerItem: the owner as a schema item
  5620. * @node: the node holding the value
  5621. *
  5622. * Converts a boolean string value into 1 or 0.
  5623. *
  5624. * Returns 0 or 1.
  5625. */
  5626. static int
  5627. xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
  5628. xmlSchemaBasicItemPtr ownerItem,
  5629. xmlNodePtr node)
  5630. {
  5631. xmlChar *value = NULL;
  5632. int res = 0;
  5633. value = xmlNodeGetContent(node);
  5634. /*
  5635. * 3.2.2.1 Lexical representation
  5636. * An instance of a datatype that is defined as �boolean�
  5637. * can have the following legal literals {true, false, 1, 0}.
  5638. */
  5639. if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
  5640. res = 1;
  5641. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
  5642. res = 0;
  5643. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
  5644. res = 1;
  5645. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
  5646. res = 0;
  5647. else {
  5648. xmlSchemaPSimpleTypeErr(ctxt,
  5649. XML_SCHEMAP_INVALID_BOOLEAN,
  5650. ownerItem, node,
  5651. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5652. NULL, BAD_CAST value,
  5653. NULL, NULL, NULL);
  5654. }
  5655. if (value != NULL)
  5656. xmlFree(value);
  5657. return (res);
  5658. }
  5659. /**
  5660. * xmlGetBooleanProp:
  5661. * @ctxt: a schema validation context
  5662. * @node: a subtree containing XML Schema informations
  5663. * @name: the attribute name
  5664. * @def: the default value
  5665. *
  5666. * Evaluate if a boolean property is set
  5667. *
  5668. * Returns the default if not found, 0 if found to be false,
  5669. * 1 if found to be true
  5670. */
  5671. static int
  5672. xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
  5673. xmlNodePtr node,
  5674. const char *name, int def)
  5675. {
  5676. const xmlChar *val;
  5677. val = xmlSchemaGetProp(ctxt, node, name);
  5678. if (val == NULL)
  5679. return (def);
  5680. /*
  5681. * 3.2.2.1 Lexical representation
  5682. * An instance of a datatype that is defined as �boolean�
  5683. * can have the following legal literals {true, false, 1, 0}.
  5684. */
  5685. if (xmlStrEqual(val, BAD_CAST "true"))
  5686. def = 1;
  5687. else if (xmlStrEqual(val, BAD_CAST "false"))
  5688. def = 0;
  5689. else if (xmlStrEqual(val, BAD_CAST "1"))
  5690. def = 1;
  5691. else if (xmlStrEqual(val, BAD_CAST "0"))
  5692. def = 0;
  5693. else {
  5694. xmlSchemaPSimpleTypeErr(ctxt,
  5695. XML_SCHEMAP_INVALID_BOOLEAN,
  5696. NULL,
  5697. (xmlNodePtr) xmlSchemaGetPropNode(node, name),
  5698. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5699. NULL, val, NULL, NULL, NULL);
  5700. }
  5701. return (def);
  5702. }
  5703. /************************************************************************
  5704. * *
  5705. * Shema extraction from an Infoset *
  5706. * *
  5707. ************************************************************************/
  5708. static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
  5709. ctxt, xmlSchemaPtr schema,
  5710. xmlNodePtr node,
  5711. int topLevel);
  5712. static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
  5713. ctxt,
  5714. xmlSchemaPtr schema,
  5715. xmlNodePtr node,
  5716. int topLevel);
  5717. static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
  5718. ctxt,
  5719. xmlSchemaPtr schema,
  5720. xmlNodePtr node,
  5721. xmlSchemaTypeType parentType);
  5722. static xmlSchemaBasicItemPtr
  5723. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  5724. xmlSchemaPtr schema,
  5725. xmlNodePtr node,
  5726. xmlSchemaItemListPtr uses,
  5727. int parentType);
  5728. static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
  5729. xmlSchemaPtr schema,
  5730. xmlNodePtr node);
  5731. static xmlSchemaWildcardPtr
  5732. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  5733. xmlSchemaPtr schema, xmlNodePtr node);
  5734. /**
  5735. * xmlSchemaPValAttrNodeValue:
  5736. *
  5737. * @ctxt: a schema parser context
  5738. * @ownerDes: the designation of the parent element
  5739. * @ownerItem: the schema object owner if existent
  5740. * @attr: the schema attribute node being validated
  5741. * @value: the value
  5742. * @type: the built-in type to be validated against
  5743. *
  5744. * Validates a value against the given built-in type.
  5745. * This one is intended to be used internally for validation
  5746. * of schema attribute values during parsing of the schema.
  5747. *
  5748. * Returns 0 if the value is valid, a positive error code
  5749. * number otherwise and -1 in case of an internal or API error.
  5750. */
  5751. static int
  5752. xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
  5753. xmlSchemaBasicItemPtr ownerItem,
  5754. xmlAttrPtr attr,
  5755. const xmlChar *value,
  5756. xmlSchemaTypePtr type)
  5757. {
  5758. int ret = 0;
  5759. /*
  5760. * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
  5761. * one is really meant to be used internally, so better not.
  5762. */
  5763. if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
  5764. return (-1);
  5765. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5766. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5767. "the given type is not a built-in type");
  5768. return (-1);
  5769. }
  5770. switch (type->builtInType) {
  5771. case XML_SCHEMAS_NCNAME:
  5772. case XML_SCHEMAS_QNAME:
  5773. case XML_SCHEMAS_ANYURI:
  5774. case XML_SCHEMAS_TOKEN:
  5775. case XML_SCHEMAS_LANGUAGE:
  5776. ret = xmlSchemaValPredefTypeNode(type, value, NULL,
  5777. (xmlNodePtr) attr);
  5778. break;
  5779. default: {
  5780. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5781. "validation using the given type is not supported while "
  5782. "parsing a schema");
  5783. return (-1);
  5784. }
  5785. }
  5786. /*
  5787. * TODO: Should we use the S4S error codes instead?
  5788. */
  5789. if (ret < 0) {
  5790. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5791. "failed to validate a schema attribute value");
  5792. return (-1);
  5793. } else if (ret > 0) {
  5794. if (WXS_IS_LIST(type))
  5795. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  5796. else
  5797. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  5798. xmlSchemaPSimpleTypeErr(pctxt,
  5799. ret, ownerItem, (xmlNodePtr) attr,
  5800. type, NULL, value, NULL, NULL, NULL);
  5801. }
  5802. return (ret);
  5803. }
  5804. /**
  5805. * xmlSchemaPValAttrNode:
  5806. *
  5807. * @ctxt: a schema parser context
  5808. * @ownerDes: the designation of the parent element
  5809. * @ownerItem: the schema object owner if existent
  5810. * @attr: the schema attribute node being validated
  5811. * @type: the built-in type to be validated against
  5812. * @value: the resulting value if any
  5813. *
  5814. * Extracts and validates a value against the given built-in type.
  5815. * This one is intended to be used internally for validation
  5816. * of schema attribute values during parsing of the schema.
  5817. *
  5818. * Returns 0 if the value is valid, a positive error code
  5819. * number otherwise and -1 in case of an internal or API error.
  5820. */
  5821. static int
  5822. xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
  5823. xmlSchemaBasicItemPtr ownerItem,
  5824. xmlAttrPtr attr,
  5825. xmlSchemaTypePtr type,
  5826. const xmlChar **value)
  5827. {
  5828. const xmlChar *val;
  5829. if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
  5830. return (-1);
  5831. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5832. if (value != NULL)
  5833. *value = val;
  5834. return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
  5835. val, type));
  5836. }
  5837. /**
  5838. * xmlSchemaPValAttr:
  5839. *
  5840. * @ctxt: a schema parser context
  5841. * @node: the element node of the attribute
  5842. * @ownerDes: the designation of the parent element
  5843. * @ownerItem: the schema object owner if existent
  5844. * @ownerElem: the owner element node
  5845. * @name: the name of the schema attribute node
  5846. * @type: the built-in type to be validated against
  5847. * @value: the resulting value if any
  5848. *
  5849. * Extracts and validates a value against the given built-in type.
  5850. * This one is intended to be used internally for validation
  5851. * of schema attribute values during parsing of the schema.
  5852. *
  5853. * Returns 0 if the value is valid, a positive error code
  5854. * number otherwise and -1 in case of an internal or API error.
  5855. */
  5856. static int
  5857. xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
  5858. xmlSchemaBasicItemPtr ownerItem,
  5859. xmlNodePtr ownerElem,
  5860. const char *name,
  5861. xmlSchemaTypePtr type,
  5862. const xmlChar **value)
  5863. {
  5864. xmlAttrPtr attr;
  5865. if ((ctxt == NULL) || (type == NULL)) {
  5866. if (value != NULL)
  5867. *value = NULL;
  5868. return (-1);
  5869. }
  5870. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5871. if (value != NULL)
  5872. *value = NULL;
  5873. xmlSchemaPErr(ctxt, ownerElem,
  5874. XML_SCHEMAP_INTERNAL,
  5875. "Internal error: xmlSchemaPValAttr, the given "
  5876. "type '%s' is not a built-in type.\n",
  5877. type->name, NULL);
  5878. return (-1);
  5879. }
  5880. attr = xmlSchemaGetPropNode(ownerElem, name);
  5881. if (attr == NULL) {
  5882. if (value != NULL)
  5883. *value = NULL;
  5884. return (0);
  5885. }
  5886. return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
  5887. type, value));
  5888. }
  5889. static int
  5890. xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
  5891. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  5892. xmlNodePtr node,
  5893. xmlAttrPtr attr,
  5894. const xmlChar *namespaceName)
  5895. {
  5896. /* TODO: Pointer comparison instead? */
  5897. if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
  5898. return (0);
  5899. if (xmlStrEqual(xmlSchemaNs, namespaceName))
  5900. return (0);
  5901. /*
  5902. * Check if the referenced namespace was <import>ed.
  5903. */
  5904. if (WXS_BUCKET(pctxt)->relations != NULL) {
  5905. xmlSchemaSchemaRelationPtr rel;
  5906. rel = WXS_BUCKET(pctxt)->relations;
  5907. do {
  5908. if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
  5909. xmlStrEqual(namespaceName, rel->importNamespace))
  5910. return (0);
  5911. rel = rel->next;
  5912. } while (rel != NULL);
  5913. }
  5914. /*
  5915. * No matching <import>ed namespace found.
  5916. */
  5917. {
  5918. xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
  5919. if (namespaceName == NULL)
  5920. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5921. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5922. "References from this schema to components in no "
  5923. "namespace are not allowed, since not indicated by an "
  5924. "import statement", NULL, NULL);
  5925. else
  5926. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5927. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5928. "References from this schema to components in the "
  5929. "namespace '%s' are not allowed, since not indicated by an "
  5930. "import statement", namespaceName, NULL);
  5931. }
  5932. return (XML_SCHEMAP_SRC_RESOLVE);
  5933. }
  5934. /**
  5935. * xmlSchemaParseLocalAttributes:
  5936. * @ctxt: a schema validation context
  5937. * @schema: the schema being built
  5938. * @node: a subtree containing XML Schema informations
  5939. * @type: the hosting type where the attributes will be anchored
  5940. *
  5941. * Parses attribute uses and attribute declarations and
  5942. * attribute group references.
  5943. */
  5944. static int
  5945. xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5946. xmlNodePtr *child, xmlSchemaItemListPtr *list,
  5947. int parentType, int *hasRefs)
  5948. {
  5949. void *item;
  5950. while ((IS_SCHEMA((*child), "attribute")) ||
  5951. (IS_SCHEMA((*child), "attributeGroup"))) {
  5952. if (IS_SCHEMA((*child), "attribute")) {
  5953. item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
  5954. *list, parentType);
  5955. } else {
  5956. item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
  5957. if ((item != NULL) && (hasRefs != NULL))
  5958. *hasRefs = 1;
  5959. }
  5960. if (item != NULL) {
  5961. if (*list == NULL) {
  5962. /* TODO: Customize grow factor. */
  5963. *list = xmlSchemaItemListCreate();
  5964. if (*list == NULL)
  5965. return(-1);
  5966. }
  5967. if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
  5968. return(-1);
  5969. }
  5970. *child = (*child)->next;
  5971. }
  5972. return (0);
  5973. }
  5974. /**
  5975. * xmlSchemaParseAnnotation:
  5976. * @ctxt: a schema validation context
  5977. * @schema: the schema being built
  5978. * @node: a subtree containing XML Schema informations
  5979. *
  5980. * parse a XML schema Attrribute declaration
  5981. * *WARNING* this interface is highly subject to change
  5982. *
  5983. * Returns -1 in case of error, 0 if the declaration is improper and
  5984. * 1 in case of success.
  5985. */
  5986. static xmlSchemaAnnotPtr
  5987. xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
  5988. {
  5989. xmlSchemaAnnotPtr ret;
  5990. xmlNodePtr child = NULL;
  5991. xmlAttrPtr attr;
  5992. int barked = 0;
  5993. /*
  5994. * INFO: S4S completed.
  5995. */
  5996. /*
  5997. * id = ID
  5998. * {any attributes with non-schema namespace . . .}>
  5999. * Content: (appinfo | documentation)*
  6000. */
  6001. if ((ctxt == NULL) || (node == NULL))
  6002. return (NULL);
  6003. if (needed)
  6004. ret = xmlSchemaNewAnnot(ctxt, node);
  6005. else
  6006. ret = NULL;
  6007. attr = node->properties;
  6008. while (attr != NULL) {
  6009. if (((attr->ns == NULL) &&
  6010. (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
  6011. ((attr->ns != NULL) &&
  6012. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6013. xmlSchemaPIllegalAttrErr(ctxt,
  6014. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6015. }
  6016. attr = attr->next;
  6017. }
  6018. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6019. /*
  6020. * And now for the children...
  6021. */
  6022. child = node->children;
  6023. while (child != NULL) {
  6024. if (IS_SCHEMA(child, "appinfo")) {
  6025. /* TODO: make available the content of "appinfo". */
  6026. /*
  6027. * source = anyURI
  6028. * {any attributes with non-schema namespace . . .}>
  6029. * Content: ({any})*
  6030. */
  6031. attr = child->properties;
  6032. while (attr != NULL) {
  6033. if (((attr->ns == NULL) &&
  6034. (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
  6035. ((attr->ns != NULL) &&
  6036. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6037. xmlSchemaPIllegalAttrErr(ctxt,
  6038. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6039. }
  6040. attr = attr->next;
  6041. }
  6042. xmlSchemaPValAttr(ctxt, NULL, child, "source",
  6043. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  6044. child = child->next;
  6045. } else if (IS_SCHEMA(child, "documentation")) {
  6046. /* TODO: make available the content of "documentation". */
  6047. /*
  6048. * source = anyURI
  6049. * {any attributes with non-schema namespace . . .}>
  6050. * Content: ({any})*
  6051. */
  6052. attr = child->properties;
  6053. while (attr != NULL) {
  6054. if (attr->ns == NULL) {
  6055. if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
  6056. xmlSchemaPIllegalAttrErr(ctxt,
  6057. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6058. }
  6059. } else {
  6060. if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
  6061. (xmlStrEqual(attr->name, BAD_CAST "lang") &&
  6062. (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
  6063. xmlSchemaPIllegalAttrErr(ctxt,
  6064. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6065. }
  6066. }
  6067. attr = attr->next;
  6068. }
  6069. /*
  6070. * Attribute "xml:lang".
  6071. */
  6072. attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
  6073. if (attr != NULL)
  6074. xmlSchemaPValAttrNode(ctxt, NULL, attr,
  6075. xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
  6076. child = child->next;
  6077. } else {
  6078. if (!barked)
  6079. xmlSchemaPContentErr(ctxt,
  6080. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6081. NULL, node, child, NULL, "(appinfo | documentation)*");
  6082. barked = 1;
  6083. child = child->next;
  6084. }
  6085. }
  6086. return (ret);
  6087. }
  6088. /**
  6089. * xmlSchemaParseFacet:
  6090. * @ctxt: a schema validation context
  6091. * @schema: the schema being built
  6092. * @node: a subtree containing XML Schema informations
  6093. *
  6094. * parse a XML schema Facet declaration
  6095. * *WARNING* this interface is highly subject to change
  6096. *
  6097. * Returns the new type structure or NULL in case of error
  6098. */
  6099. static xmlSchemaFacetPtr
  6100. xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6101. xmlNodePtr node)
  6102. {
  6103. xmlSchemaFacetPtr facet;
  6104. xmlNodePtr child = NULL;
  6105. const xmlChar *value;
  6106. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6107. return (NULL);
  6108. facet = xmlSchemaNewFacet();
  6109. if (facet == NULL) {
  6110. xmlSchemaPErrMemory(ctxt, "allocating facet", node);
  6111. return (NULL);
  6112. }
  6113. facet->node = node;
  6114. value = xmlSchemaGetProp(ctxt, node, "value");
  6115. if (value == NULL) {
  6116. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
  6117. "Facet %s has no value\n", node->name, NULL);
  6118. xmlSchemaFreeFacet(facet);
  6119. return (NULL);
  6120. }
  6121. if (IS_SCHEMA(node, "minInclusive")) {
  6122. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  6123. } else if (IS_SCHEMA(node, "minExclusive")) {
  6124. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  6125. } else if (IS_SCHEMA(node, "maxInclusive")) {
  6126. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  6127. } else if (IS_SCHEMA(node, "maxExclusive")) {
  6128. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  6129. } else if (IS_SCHEMA(node, "totalDigits")) {
  6130. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  6131. } else if (IS_SCHEMA(node, "fractionDigits")) {
  6132. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  6133. } else if (IS_SCHEMA(node, "pattern")) {
  6134. facet->type = XML_SCHEMA_FACET_PATTERN;
  6135. } else if (IS_SCHEMA(node, "enumeration")) {
  6136. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  6137. } else if (IS_SCHEMA(node, "whiteSpace")) {
  6138. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  6139. } else if (IS_SCHEMA(node, "length")) {
  6140. facet->type = XML_SCHEMA_FACET_LENGTH;
  6141. } else if (IS_SCHEMA(node, "maxLength")) {
  6142. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  6143. } else if (IS_SCHEMA(node, "minLength")) {
  6144. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  6145. } else {
  6146. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
  6147. "Unknown facet type %s\n", node->name, NULL);
  6148. xmlSchemaFreeFacet(facet);
  6149. return (NULL);
  6150. }
  6151. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6152. facet->value = value;
  6153. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  6154. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  6155. const xmlChar *fixed;
  6156. fixed = xmlSchemaGetProp(ctxt, node, "fixed");
  6157. if (fixed != NULL) {
  6158. if (xmlStrEqual(fixed, BAD_CAST "true"))
  6159. facet->fixed = 1;
  6160. }
  6161. }
  6162. child = node->children;
  6163. if (IS_SCHEMA(child, "annotation")) {
  6164. facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6165. child = child->next;
  6166. }
  6167. if (child != NULL) {
  6168. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
  6169. "Facet %s has unexpected child content\n",
  6170. node->name, NULL);
  6171. }
  6172. return (facet);
  6173. }
  6174. /**
  6175. * xmlSchemaParseWildcardNs:
  6176. * @ctxt: a schema parser context
  6177. * @wildc: the wildcard, already created
  6178. * @node: a subtree containing XML Schema informations
  6179. *
  6180. * Parses the attribute "processContents" and "namespace"
  6181. * of a xsd:anyAttribute and xsd:any.
  6182. * *WARNING* this interface is highly subject to change
  6183. *
  6184. * Returns 0 if everything goes fine, a positive error code
  6185. * if something is not valid and -1 if an internal error occurs.
  6186. */
  6187. static int
  6188. xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
  6189. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  6190. xmlSchemaWildcardPtr wildc,
  6191. xmlNodePtr node)
  6192. {
  6193. const xmlChar *pc, *ns, *dictnsItem;
  6194. int ret = 0;
  6195. xmlChar *nsItem;
  6196. xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
  6197. xmlAttrPtr attr;
  6198. pc = xmlSchemaGetProp(ctxt, node, "processContents");
  6199. if ((pc == NULL)
  6200. || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
  6201. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6202. } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
  6203. wildc->processContents = XML_SCHEMAS_ANY_SKIP;
  6204. } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
  6205. wildc->processContents = XML_SCHEMAS_ANY_LAX;
  6206. } else {
  6207. xmlSchemaPSimpleTypeErr(ctxt,
  6208. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6209. NULL, node,
  6210. NULL, "(strict | skip | lax)", pc,
  6211. NULL, NULL, NULL);
  6212. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6213. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  6214. }
  6215. /*
  6216. * Build the namespace constraints.
  6217. */
  6218. attr = xmlSchemaGetPropNode(node, "namespace");
  6219. ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  6220. if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
  6221. wildc->any = 1;
  6222. else if (xmlStrEqual(ns, BAD_CAST "##other")) {
  6223. wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  6224. if (wildc->negNsSet == NULL) {
  6225. return (-1);
  6226. }
  6227. wildc->negNsSet->value = ctxt->targetNamespace;
  6228. } else {
  6229. const xmlChar *end, *cur;
  6230. cur = ns;
  6231. do {
  6232. while (IS_BLANK_CH(*cur))
  6233. cur++;
  6234. end = cur;
  6235. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  6236. end++;
  6237. if (end == cur)
  6238. break;
  6239. nsItem = xmlStrndup(cur, end - cur);
  6240. if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
  6241. (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
  6242. xmlSchemaPSimpleTypeErr(ctxt,
  6243. XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
  6244. NULL, (xmlNodePtr) attr,
  6245. NULL,
  6246. "((##any | ##other) | List of (xs:anyURI | "
  6247. "(##targetNamespace | ##local)))",
  6248. nsItem, NULL, NULL, NULL);
  6249. ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
  6250. } else {
  6251. if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
  6252. dictnsItem = ctxt->targetNamespace;
  6253. } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
  6254. dictnsItem = NULL;
  6255. } else {
  6256. /*
  6257. * Validate the item (anyURI).
  6258. */
  6259. xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
  6260. nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
  6261. dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
  6262. }
  6263. /*
  6264. * Avoid dublicate namespaces.
  6265. */
  6266. tmp = wildc->nsSet;
  6267. while (tmp != NULL) {
  6268. if (dictnsItem == tmp->value)
  6269. break;
  6270. tmp = tmp->next;
  6271. }
  6272. if (tmp == NULL) {
  6273. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  6274. if (tmp == NULL) {
  6275. xmlFree(nsItem);
  6276. return (-1);
  6277. }
  6278. tmp->value = dictnsItem;
  6279. tmp->next = NULL;
  6280. if (wildc->nsSet == NULL)
  6281. wildc->nsSet = tmp;
  6282. else if (lastNs != NULL)
  6283. lastNs->next = tmp;
  6284. lastNs = tmp;
  6285. }
  6286. }
  6287. xmlFree(nsItem);
  6288. cur = end;
  6289. } while (*cur != 0);
  6290. }
  6291. return (ret);
  6292. }
  6293. static int
  6294. xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
  6295. xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
  6296. xmlNodePtr node,
  6297. int minOccurs,
  6298. int maxOccurs) {
  6299. if ((maxOccurs == 0) && ( minOccurs == 0))
  6300. return (0);
  6301. if (maxOccurs != UNBOUNDED) {
  6302. /*
  6303. * TODO: Maybe we should better not create the particle,
  6304. * if min/max is invalid, since it could confuse the build of the
  6305. * content model.
  6306. */
  6307. /*
  6308. * 3.9.6 Schema Component Constraint: Particle Correct
  6309. *
  6310. */
  6311. if (maxOccurs < 1) {
  6312. /*
  6313. * 2.2 {max occurs} must be greater than or equal to 1.
  6314. */
  6315. xmlSchemaPCustomAttrErr(ctxt,
  6316. XML_SCHEMAP_P_PROPS_CORRECT_2_2,
  6317. NULL, NULL,
  6318. xmlSchemaGetPropNode(node, "maxOccurs"),
  6319. "The value must be greater than or equal to 1");
  6320. return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
  6321. } else if (minOccurs > maxOccurs) {
  6322. /*
  6323. * 2.1 {min occurs} must not be greater than {max occurs}.
  6324. */
  6325. xmlSchemaPCustomAttrErr(ctxt,
  6326. XML_SCHEMAP_P_PROPS_CORRECT_2_1,
  6327. NULL, NULL,
  6328. xmlSchemaGetPropNode(node, "minOccurs"),
  6329. "The value must not be greater than the value of 'maxOccurs'");
  6330. return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
  6331. }
  6332. }
  6333. return (0);
  6334. }
  6335. /**
  6336. * xmlSchemaParseAny:
  6337. * @ctxt: a schema validation context
  6338. * @schema: the schema being built
  6339. * @node: a subtree containing XML Schema informations
  6340. *
  6341. * Parsea a XML schema <any> element. A particle and wildcard
  6342. * will be created (except if minOccurs==maxOccurs==0, in this case
  6343. * nothing will be created).
  6344. * *WARNING* this interface is highly subject to change
  6345. *
  6346. * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
  6347. */
  6348. static xmlSchemaParticlePtr
  6349. xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6350. xmlNodePtr node)
  6351. {
  6352. xmlSchemaParticlePtr particle;
  6353. xmlNodePtr child = NULL;
  6354. xmlSchemaWildcardPtr wild;
  6355. int min, max;
  6356. xmlAttrPtr attr;
  6357. xmlSchemaAnnotPtr annot = NULL;
  6358. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6359. return (NULL);
  6360. /*
  6361. * Check for illegal attributes.
  6362. */
  6363. attr = node->properties;
  6364. while (attr != NULL) {
  6365. if (attr->ns == NULL) {
  6366. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6367. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  6368. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  6369. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6370. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6371. xmlSchemaPIllegalAttrErr(ctxt,
  6372. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6373. }
  6374. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6375. xmlSchemaPIllegalAttrErr(ctxt,
  6376. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6377. }
  6378. attr = attr->next;
  6379. }
  6380. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6381. /*
  6382. * minOccurs/maxOccurs.
  6383. */
  6384. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  6385. "(xs:nonNegativeInteger | unbounded)");
  6386. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
  6387. "xs:nonNegativeInteger");
  6388. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  6389. /*
  6390. * Create & parse the wildcard.
  6391. */
  6392. wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
  6393. if (wild == NULL)
  6394. return (NULL);
  6395. xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
  6396. /*
  6397. * And now for the children...
  6398. */
  6399. child = node->children;
  6400. if (IS_SCHEMA(child, "annotation")) {
  6401. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6402. child = child->next;
  6403. }
  6404. if (child != NULL) {
  6405. xmlSchemaPContentErr(ctxt,
  6406. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6407. NULL, node, child,
  6408. NULL, "(annotation?)");
  6409. }
  6410. /*
  6411. * No component if minOccurs==maxOccurs==0.
  6412. */
  6413. if ((min == 0) && (max == 0)) {
  6414. /* Don't free the wildcard, since it's already on the list. */
  6415. return (NULL);
  6416. }
  6417. /*
  6418. * Create the particle.
  6419. */
  6420. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  6421. if (particle == NULL)
  6422. return (NULL);
  6423. particle->annot = annot;
  6424. particle->children = (xmlSchemaTreeItemPtr) wild;
  6425. return (particle);
  6426. }
  6427. /**
  6428. * xmlSchemaParseNotation:
  6429. * @ctxt: a schema validation context
  6430. * @schema: the schema being built
  6431. * @node: a subtree containing XML Schema informations
  6432. *
  6433. * parse a XML schema Notation declaration
  6434. *
  6435. * Returns the new structure or NULL in case of error
  6436. */
  6437. static xmlSchemaNotationPtr
  6438. xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6439. xmlNodePtr node)
  6440. {
  6441. const xmlChar *name;
  6442. xmlSchemaNotationPtr ret;
  6443. xmlNodePtr child = NULL;
  6444. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6445. return (NULL);
  6446. name = xmlSchemaGetProp(ctxt, node, "name");
  6447. if (name == NULL) {
  6448. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
  6449. "Notation has no name\n", NULL, NULL);
  6450. return (NULL);
  6451. }
  6452. ret = xmlSchemaAddNotation(ctxt, schema, name,
  6453. ctxt->targetNamespace, node);
  6454. if (ret == NULL)
  6455. return (NULL);
  6456. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6457. child = node->children;
  6458. if (IS_SCHEMA(child, "annotation")) {
  6459. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6460. child = child->next;
  6461. }
  6462. if (child != NULL) {
  6463. xmlSchemaPContentErr(ctxt,
  6464. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6465. NULL, node, child,
  6466. NULL, "(annotation?)");
  6467. }
  6468. return (ret);
  6469. }
  6470. /**
  6471. * xmlSchemaParseAnyAttribute:
  6472. * @ctxt: a schema validation context
  6473. * @schema: the schema being built
  6474. * @node: a subtree containing XML Schema informations
  6475. *
  6476. * parse a XML schema AnyAttrribute declaration
  6477. * *WARNING* this interface is highly subject to change
  6478. *
  6479. * Returns a wildcard or NULL.
  6480. */
  6481. static xmlSchemaWildcardPtr
  6482. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  6483. xmlSchemaPtr schema, xmlNodePtr node)
  6484. {
  6485. xmlSchemaWildcardPtr ret;
  6486. xmlNodePtr child = NULL;
  6487. xmlAttrPtr attr;
  6488. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6489. return (NULL);
  6490. ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  6491. node);
  6492. if (ret == NULL) {
  6493. return (NULL);
  6494. }
  6495. /*
  6496. * Check for illegal attributes.
  6497. */
  6498. attr = node->properties;
  6499. while (attr != NULL) {
  6500. if (attr->ns == NULL) {
  6501. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6502. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6503. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6504. xmlSchemaPIllegalAttrErr(ctxt,
  6505. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6506. }
  6507. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6508. xmlSchemaPIllegalAttrErr(ctxt,
  6509. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6510. }
  6511. attr = attr->next;
  6512. }
  6513. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6514. /*
  6515. * Parse the namespace list.
  6516. */
  6517. if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
  6518. return (NULL);
  6519. /*
  6520. * And now for the children...
  6521. */
  6522. child = node->children;
  6523. if (IS_SCHEMA(child, "annotation")) {
  6524. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6525. child = child->next;
  6526. }
  6527. if (child != NULL) {
  6528. xmlSchemaPContentErr(ctxt,
  6529. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6530. NULL, node, child,
  6531. NULL, "(annotation?)");
  6532. }
  6533. return (ret);
  6534. }
  6535. /**
  6536. * xmlSchemaParseAttribute:
  6537. * @ctxt: a schema validation context
  6538. * @schema: the schema being built
  6539. * @node: a subtree containing XML Schema informations
  6540. *
  6541. * parse a XML schema Attrribute declaration
  6542. * *WARNING* this interface is highly subject to change
  6543. *
  6544. * Returns the attribute declaration.
  6545. */
  6546. static xmlSchemaBasicItemPtr
  6547. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6548. xmlSchemaPtr schema,
  6549. xmlNodePtr node,
  6550. xmlSchemaItemListPtr uses,
  6551. int parentType)
  6552. {
  6553. const xmlChar *attrValue, *name = NULL, *ns = NULL;
  6554. xmlSchemaAttributeUsePtr use = NULL;
  6555. xmlNodePtr child = NULL;
  6556. xmlAttrPtr attr;
  6557. const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
  6558. int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6559. int nberrors, hasForm = 0, defValueType = 0;
  6560. #define WXS_ATTR_DEF_VAL_DEFAULT 1
  6561. #define WXS_ATTR_DEF_VAL_FIXED 2
  6562. /*
  6563. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6564. */
  6565. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6566. return (NULL);
  6567. attr = xmlSchemaGetPropNode(node, "ref");
  6568. if (attr != NULL) {
  6569. if (xmlSchemaPValAttrNodeQName(pctxt, schema,
  6570. NULL, attr, &tmpNs, &tmpName) != 0) {
  6571. return (NULL);
  6572. }
  6573. if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
  6574. return(NULL);
  6575. isRef = 1;
  6576. }
  6577. nberrors = pctxt->nberrors;
  6578. /*
  6579. * Check for illegal attributes.
  6580. */
  6581. attr = node->properties;
  6582. while (attr != NULL) {
  6583. if (attr->ns == NULL) {
  6584. if (isRef) {
  6585. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6586. xmlSchemaPValAttrNodeID(pctxt, attr);
  6587. goto attr_next;
  6588. } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
  6589. goto attr_next;
  6590. }
  6591. } else {
  6592. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  6593. goto attr_next;
  6594. } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6595. xmlSchemaPValAttrNodeID(pctxt, attr);
  6596. goto attr_next;
  6597. } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
  6598. xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
  6599. attr, &tmpNs, &tmpName);
  6600. goto attr_next;
  6601. } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
  6602. /*
  6603. * Evaluate the target namespace
  6604. */
  6605. hasForm = 1;
  6606. attrValue = xmlSchemaGetNodeContent(pctxt,
  6607. (xmlNodePtr) attr);
  6608. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  6609. ns = pctxt->targetNamespace;
  6610. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
  6611. {
  6612. xmlSchemaPSimpleTypeErr(pctxt,
  6613. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6614. NULL, (xmlNodePtr) attr,
  6615. NULL, "(qualified | unqualified)",
  6616. attrValue, NULL, NULL, NULL);
  6617. }
  6618. goto attr_next;
  6619. }
  6620. }
  6621. if (xmlStrEqual(attr->name, BAD_CAST "use")) {
  6622. attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6623. /* TODO: Maybe we need to normalize the value beforehand. */
  6624. if (xmlStrEqual(attrValue, BAD_CAST "optional"))
  6625. occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6626. else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
  6627. occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
  6628. else if (xmlStrEqual(attrValue, BAD_CAST "required"))
  6629. occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
  6630. else {
  6631. xmlSchemaPSimpleTypeErr(pctxt,
  6632. XML_SCHEMAP_INVALID_ATTR_USE,
  6633. NULL, (xmlNodePtr) attr,
  6634. NULL, "(optional | prohibited | required)",
  6635. attrValue, NULL, NULL, NULL);
  6636. }
  6637. goto attr_next;
  6638. } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
  6639. /*
  6640. * 3.2.3 : 1
  6641. * default and fixed must not both be present.
  6642. */
  6643. if (defValue) {
  6644. xmlSchemaPMutualExclAttrErr(pctxt,
  6645. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6646. NULL, attr, "default", "fixed");
  6647. } else {
  6648. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6649. defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
  6650. }
  6651. goto attr_next;
  6652. } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
  6653. /*
  6654. * 3.2.3 : 1
  6655. * default and fixed must not both be present.
  6656. */
  6657. if (defValue) {
  6658. xmlSchemaPMutualExclAttrErr(pctxt,
  6659. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6660. NULL, attr, "default", "fixed");
  6661. } else {
  6662. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6663. defValueType = WXS_ATTR_DEF_VAL_FIXED;
  6664. }
  6665. goto attr_next;
  6666. }
  6667. } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
  6668. goto attr_next;
  6669. xmlSchemaPIllegalAttrErr(pctxt,
  6670. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6671. attr_next:
  6672. attr = attr->next;
  6673. }
  6674. /*
  6675. * 3.2.3 : 2
  6676. * If default and use are both present, use must have
  6677. * the actual value optional.
  6678. */
  6679. if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
  6680. (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
  6681. xmlSchemaPSimpleTypeErr(pctxt,
  6682. XML_SCHEMAP_SRC_ATTRIBUTE_2,
  6683. NULL, node, NULL,
  6684. "(optional | prohibited | required)", NULL,
  6685. "The value of the attribute 'use' must be 'optional' "
  6686. "if the attribute 'default' is present",
  6687. NULL, NULL);
  6688. }
  6689. /*
  6690. * We want correct attributes.
  6691. */
  6692. if (nberrors != pctxt->nberrors)
  6693. return(NULL);
  6694. if (! isRef) {
  6695. xmlSchemaAttributePtr attrDecl;
  6696. /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
  6697. if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
  6698. ns = pctxt->targetNamespace;
  6699. /*
  6700. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6701. * TODO: Move this to the component layer.
  6702. */
  6703. if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
  6704. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6705. XML_SCHEMAP_NO_XSI,
  6706. node, NULL,
  6707. "The target namespace must not match '%s'",
  6708. xmlSchemaInstanceNs, NULL);
  6709. }
  6710. attr = xmlSchemaGetPropNode(node, "name");
  6711. if (attr == NULL) {
  6712. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6713. NULL, node, "name", NULL);
  6714. return (NULL);
  6715. }
  6716. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6717. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  6718. return (NULL);
  6719. }
  6720. /*
  6721. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6722. * TODO: Move this to the component layer.
  6723. */
  6724. if (xmlStrEqual(name, BAD_CAST "xmlns")) {
  6725. xmlSchemaPSimpleTypeErr(pctxt,
  6726. XML_SCHEMAP_NO_XMLNS,
  6727. NULL, (xmlNodePtr) attr,
  6728. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6729. "The value of the attribute must not match 'xmlns'",
  6730. NULL, NULL);
  6731. return (NULL);
  6732. }
  6733. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
  6734. goto check_children;
  6735. /*
  6736. * Create the attribute use component.
  6737. */
  6738. use = xmlSchemaAddAttributeUse(pctxt, node);
  6739. if (use == NULL)
  6740. return(NULL);
  6741. use->occurs = occurs;
  6742. /*
  6743. * Create the attribute declaration.
  6744. */
  6745. attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
  6746. if (attrDecl == NULL)
  6747. return (NULL);
  6748. if (tmpName != NULL) {
  6749. attrDecl->typeName = tmpName;
  6750. attrDecl->typeNs = tmpNs;
  6751. }
  6752. use->attrDecl = attrDecl;
  6753. /*
  6754. * Value constraint.
  6755. */
  6756. if (defValue != NULL) {
  6757. attrDecl->defValue = defValue;
  6758. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6759. attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
  6760. }
  6761. } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6762. xmlSchemaQNameRefPtr ref;
  6763. /*
  6764. * Create the attribute use component.
  6765. */
  6766. use = xmlSchemaAddAttributeUse(pctxt, node);
  6767. if (use == NULL)
  6768. return(NULL);
  6769. /*
  6770. * We need to resolve the reference at later stage.
  6771. */
  6772. WXS_ADD_PENDING(pctxt, use);
  6773. use->occurs = occurs;
  6774. /*
  6775. * Create a QName reference to the attribute declaration.
  6776. */
  6777. ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
  6778. tmpName, tmpNs);
  6779. if (ref == NULL)
  6780. return(NULL);
  6781. /*
  6782. * Assign the reference. This will be substituted for the
  6783. * referenced attribute declaration when the QName is resolved.
  6784. */
  6785. use->attrDecl = WXS_ATTR_CAST ref;
  6786. /*
  6787. * Value constraint.
  6788. */
  6789. if (defValue != NULL)
  6790. use->defValue = defValue;
  6791. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6792. use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
  6793. }
  6794. check_children:
  6795. /*
  6796. * And now for the children...
  6797. */
  6798. child = node->children;
  6799. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6800. xmlSchemaAttributeUseProhibPtr prohib;
  6801. if (IS_SCHEMA(child, "annotation")) {
  6802. xmlSchemaParseAnnotation(pctxt, child, 0);
  6803. child = child->next;
  6804. }
  6805. if (child != NULL) {
  6806. xmlSchemaPContentErr(pctxt,
  6807. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6808. NULL, node, child, NULL,
  6809. "(annotation?)");
  6810. }
  6811. /*
  6812. * Check for pointlessness of attribute prohibitions.
  6813. */
  6814. if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
  6815. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6816. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6817. node, NULL,
  6818. "Skipping attribute use prohibition, since it is "
  6819. "pointless inside an <attributeGroup>",
  6820. NULL, NULL, NULL);
  6821. return(NULL);
  6822. } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
  6823. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6824. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6825. node, NULL,
  6826. "Skipping attribute use prohibition, since it is "
  6827. "pointless when extending a type",
  6828. NULL, NULL, NULL);
  6829. return(NULL);
  6830. }
  6831. if (! isRef) {
  6832. tmpName = name;
  6833. tmpNs = ns;
  6834. }
  6835. /*
  6836. * Check for duplicate attribute prohibitions.
  6837. */
  6838. if (uses) {
  6839. int i;
  6840. for (i = 0; i < uses->nbItems; i++) {
  6841. use = uses->items[i];
  6842. if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
  6843. (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
  6844. (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
  6845. {
  6846. xmlChar *str = NULL;
  6847. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6848. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6849. node, NULL,
  6850. "Skipping duplicate attribute use prohibition '%s'",
  6851. xmlSchemaFormatQName(&str, tmpNs, tmpName),
  6852. NULL, NULL);
  6853. FREE_AND_NULL(str)
  6854. return(NULL);
  6855. }
  6856. }
  6857. }
  6858. /*
  6859. * Create the attribute prohibition helper component.
  6860. */
  6861. prohib = xmlSchemaAddAttributeUseProhib(pctxt);
  6862. if (prohib == NULL)
  6863. return(NULL);
  6864. prohib->node = node;
  6865. prohib->name = tmpName;
  6866. prohib->targetNamespace = tmpNs;
  6867. if (isRef) {
  6868. /*
  6869. * We need at least to resolve to the attribute declaration.
  6870. */
  6871. WXS_ADD_PENDING(pctxt, prohib);
  6872. }
  6873. return(WXS_BASIC_CAST prohib);
  6874. } else {
  6875. if (IS_SCHEMA(child, "annotation")) {
  6876. /*
  6877. * TODO: Should this go into the attr decl?
  6878. */
  6879. use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  6880. child = child->next;
  6881. }
  6882. if (isRef) {
  6883. if (child != NULL) {
  6884. if (IS_SCHEMA(child, "simpleType"))
  6885. /*
  6886. * 3.2.3 : 3.2
  6887. * If ref is present, then all of <simpleType>,
  6888. * form and type must be absent.
  6889. */
  6890. xmlSchemaPContentErr(pctxt,
  6891. XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
  6892. NULL, node, child, NULL,
  6893. "(annotation?)");
  6894. else
  6895. xmlSchemaPContentErr(pctxt,
  6896. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6897. NULL, node, child, NULL,
  6898. "(annotation?)");
  6899. }
  6900. } else {
  6901. if (IS_SCHEMA(child, "simpleType")) {
  6902. if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
  6903. /*
  6904. * 3.2.3 : 4
  6905. * type and <simpleType> must not both be present.
  6906. */
  6907. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  6908. NULL, node, child,
  6909. "The attribute 'type' and the <simpleType> child "
  6910. "are mutually exclusive", NULL);
  6911. } else
  6912. WXS_ATTRUSE_TYPEDEF(use) =
  6913. xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  6914. child = child->next;
  6915. }
  6916. if (child != NULL)
  6917. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6918. NULL, node, child, NULL,
  6919. "(annotation?, simpleType?)");
  6920. }
  6921. }
  6922. return (WXS_BASIC_CAST use);
  6923. }
  6924. static xmlSchemaAttributePtr
  6925. xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6926. xmlSchemaPtr schema,
  6927. xmlNodePtr node)
  6928. {
  6929. const xmlChar *attrValue;
  6930. xmlSchemaAttributePtr ret;
  6931. xmlNodePtr child = NULL;
  6932. xmlAttrPtr attr;
  6933. /*
  6934. * Note that the w3c spec assumes the schema to be validated with schema
  6935. * for schemas beforehand.
  6936. *
  6937. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6938. */
  6939. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6940. return (NULL);
  6941. /*
  6942. * 3.2.3 : 3.1
  6943. * One of ref or name must be present, but not both
  6944. */
  6945. attr = xmlSchemaGetPropNode(node, "name");
  6946. if (attr == NULL) {
  6947. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6948. NULL, node, "name", NULL);
  6949. return (NULL);
  6950. }
  6951. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6952. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
  6953. return (NULL);
  6954. }
  6955. /*
  6956. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6957. * TODO: Move this to the component layer.
  6958. */
  6959. if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
  6960. xmlSchemaPSimpleTypeErr(pctxt,
  6961. XML_SCHEMAP_NO_XMLNS,
  6962. NULL, (xmlNodePtr) attr,
  6963. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6964. "The value of the attribute must not match 'xmlns'",
  6965. NULL, NULL);
  6966. return (NULL);
  6967. }
  6968. /*
  6969. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6970. * TODO: Move this to the component layer.
  6971. * Or better leave it here and add it to the component layer
  6972. * if we have a schema construction API.
  6973. */
  6974. if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
  6975. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6976. XML_SCHEMAP_NO_XSI, node, NULL,
  6977. "The target namespace must not match '%s'",
  6978. xmlSchemaInstanceNs, NULL);
  6979. }
  6980. ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
  6981. pctxt->targetNamespace, node, 1);
  6982. if (ret == NULL)
  6983. return (NULL);
  6984. ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
  6985. /*
  6986. * Check for illegal attributes.
  6987. */
  6988. attr = node->properties;
  6989. while (attr != NULL) {
  6990. if (attr->ns == NULL) {
  6991. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6992. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  6993. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  6994. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  6995. (!xmlStrEqual(attr->name, BAD_CAST "type")))
  6996. {
  6997. xmlSchemaPIllegalAttrErr(pctxt,
  6998. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6999. }
  7000. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7001. xmlSchemaPIllegalAttrErr(pctxt,
  7002. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7003. }
  7004. attr = attr->next;
  7005. }
  7006. xmlSchemaPValAttrQName(pctxt, schema, NULL,
  7007. node, "type", &ret->typeNs, &ret->typeName);
  7008. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7009. /*
  7010. * Attribute "fixed".
  7011. */
  7012. ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
  7013. if (ret->defValue != NULL)
  7014. ret->flags |= XML_SCHEMAS_ATTR_FIXED;
  7015. /*
  7016. * Attribute "default".
  7017. */
  7018. attr = xmlSchemaGetPropNode(node, "default");
  7019. if (attr != NULL) {
  7020. /*
  7021. * 3.2.3 : 1
  7022. * default and fixed must not both be present.
  7023. */
  7024. if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
  7025. xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
  7026. WXS_BASIC_CAST ret, attr, "default", "fixed");
  7027. } else
  7028. ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  7029. }
  7030. /*
  7031. * And now for the children...
  7032. */
  7033. child = node->children;
  7034. if (IS_SCHEMA(child, "annotation")) {
  7035. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7036. child = child->next;
  7037. }
  7038. if (IS_SCHEMA(child, "simpleType")) {
  7039. if (ret->typeName != NULL) {
  7040. /*
  7041. * 3.2.3 : 4
  7042. * type and <simpleType> must not both be present.
  7043. */
  7044. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7045. NULL, node, child,
  7046. "The attribute 'type' and the <simpleType> child "
  7047. "are mutually exclusive", NULL);
  7048. } else
  7049. ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7050. child = child->next;
  7051. }
  7052. if (child != NULL)
  7053. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7054. NULL, node, child, NULL,
  7055. "(annotation?, simpleType?)");
  7056. return (ret);
  7057. }
  7058. /**
  7059. * xmlSchemaParseAttributeGroupRef:
  7060. * @ctxt: a schema validation context
  7061. * @schema: the schema being built
  7062. * @node: a subtree containing XML Schema informations
  7063. *
  7064. * Parse an attribute group definition reference.
  7065. * Note that a reference to an attribute group does not
  7066. * correspond to any component at all.
  7067. * *WARNING* this interface is highly subject to change
  7068. *
  7069. * Returns the attribute group or NULL in case of error.
  7070. */
  7071. static xmlSchemaQNameRefPtr
  7072. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  7073. xmlSchemaPtr schema,
  7074. xmlNodePtr node)
  7075. {
  7076. xmlSchemaQNameRefPtr ret;
  7077. xmlNodePtr child = NULL;
  7078. xmlAttrPtr attr;
  7079. const xmlChar *refNs = NULL, *ref = NULL;
  7080. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7081. return (NULL);
  7082. attr = xmlSchemaGetPropNode(node, "ref");
  7083. if (attr == NULL) {
  7084. xmlSchemaPMissingAttrErr(pctxt,
  7085. XML_SCHEMAP_S4S_ATTR_MISSING,
  7086. NULL, node, "ref", NULL);
  7087. return (NULL);
  7088. }
  7089. xmlSchemaPValAttrNodeQName(pctxt, schema,
  7090. NULL, attr, &refNs, &ref);
  7091. if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
  7092. return(NULL);
  7093. /*
  7094. * Check for illegal attributes.
  7095. */
  7096. attr = node->properties;
  7097. while (attr != NULL) {
  7098. if (attr->ns == NULL) {
  7099. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  7100. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7101. {
  7102. xmlSchemaPIllegalAttrErr(pctxt,
  7103. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7104. }
  7105. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7106. xmlSchemaPIllegalAttrErr(pctxt,
  7107. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7108. }
  7109. attr = attr->next;
  7110. }
  7111. /* Attribute ID */
  7112. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7113. /*
  7114. * And now for the children...
  7115. */
  7116. child = node->children;
  7117. if (IS_SCHEMA(child, "annotation")) {
  7118. /*
  7119. * TODO: We do not have a place to store the annotation, do we?
  7120. */
  7121. xmlSchemaParseAnnotation(pctxt, child, 0);
  7122. child = child->next;
  7123. }
  7124. if (child != NULL) {
  7125. xmlSchemaPContentErr(pctxt,
  7126. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7127. NULL, node, child, NULL,
  7128. "(annotation?)");
  7129. }
  7130. /*
  7131. * Handle attribute group redefinitions.
  7132. */
  7133. if (pctxt->isRedefine && pctxt->redef &&
  7134. (pctxt->redef->item->type ==
  7135. XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  7136. (ref == pctxt->redef->refName) &&
  7137. (refNs == pctxt->redef->refTargetNs))
  7138. {
  7139. /*
  7140. * SPEC src-redefine:
  7141. * (7.1) "If it has an <attributeGroup> among its contents
  7142. * the �actual value� of whose ref [attribute] is the same
  7143. * as the �actual value� of its own name attribute plus
  7144. * target namespace, then it must have exactly one such group."
  7145. */
  7146. if (pctxt->redefCounter != 0) {
  7147. xmlChar *str = NULL;
  7148. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7149. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  7150. "The redefining attribute group definition "
  7151. "'%s' must not contain more than one "
  7152. "reference to the redefined definition",
  7153. xmlSchemaFormatQName(&str, refNs, ref), NULL);
  7154. FREE_AND_NULL(str);
  7155. return(NULL);
  7156. }
  7157. pctxt->redefCounter++;
  7158. /*
  7159. * URGENT TODO: How to ensure that the reference will not be
  7160. * handled by the normal component resolution mechanism?
  7161. */
  7162. ret = xmlSchemaNewQNameRef(pctxt,
  7163. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7164. if (ret == NULL)
  7165. return(NULL);
  7166. ret->node = node;
  7167. pctxt->redef->reference = WXS_BASIC_CAST ret;
  7168. } else {
  7169. /*
  7170. * Create a QName-reference helper component. We will substitute this
  7171. * component for the attribute uses of the referenced attribute group
  7172. * definition.
  7173. */
  7174. ret = xmlSchemaNewQNameRef(pctxt,
  7175. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7176. if (ret == NULL)
  7177. return(NULL);
  7178. ret->node = node;
  7179. /* Add to pending items, to be able to resolve the reference. */
  7180. WXS_ADD_PENDING(pctxt, ret);
  7181. }
  7182. return (ret);
  7183. }
  7184. /**
  7185. * xmlSchemaParseAttributeGroupDefinition:
  7186. * @pctxt: a schema validation context
  7187. * @schema: the schema being built
  7188. * @node: a subtree containing XML Schema informations
  7189. *
  7190. * parse a XML schema Attribute Group declaration
  7191. * *WARNING* this interface is highly subject to change
  7192. *
  7193. * Returns the attribute group definition or NULL in case of error.
  7194. */
  7195. static xmlSchemaAttributeGroupPtr
  7196. xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  7197. xmlSchemaPtr schema,
  7198. xmlNodePtr node)
  7199. {
  7200. const xmlChar *name;
  7201. xmlSchemaAttributeGroupPtr ret;
  7202. xmlNodePtr child = NULL;
  7203. xmlAttrPtr attr;
  7204. int hasRefs = 0;
  7205. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7206. return (NULL);
  7207. attr = xmlSchemaGetPropNode(node, "name");
  7208. if (attr == NULL) {
  7209. xmlSchemaPMissingAttrErr(pctxt,
  7210. XML_SCHEMAP_S4S_ATTR_MISSING,
  7211. NULL, node, "name", NULL);
  7212. return (NULL);
  7213. }
  7214. /*
  7215. * The name is crucial, exit if invalid.
  7216. */
  7217. if (xmlSchemaPValAttrNode(pctxt,
  7218. NULL, attr,
  7219. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7220. return (NULL);
  7221. }
  7222. ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
  7223. name, pctxt->targetNamespace, node);
  7224. if (ret == NULL)
  7225. return (NULL);
  7226. /*
  7227. * Check for illegal attributes.
  7228. */
  7229. attr = node->properties;
  7230. while (attr != NULL) {
  7231. if (attr->ns == NULL) {
  7232. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7233. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7234. {
  7235. xmlSchemaPIllegalAttrErr(pctxt,
  7236. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7237. }
  7238. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7239. xmlSchemaPIllegalAttrErr(pctxt,
  7240. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7241. }
  7242. attr = attr->next;
  7243. }
  7244. /* Attribute ID */
  7245. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7246. /*
  7247. * And now for the children...
  7248. */
  7249. child = node->children;
  7250. if (IS_SCHEMA(child, "annotation")) {
  7251. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7252. child = child->next;
  7253. }
  7254. /*
  7255. * Parse contained attribute decls/refs.
  7256. */
  7257. if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
  7258. (xmlSchemaItemListPtr *) &(ret->attrUses),
  7259. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
  7260. return(NULL);
  7261. if (hasRefs)
  7262. ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
  7263. /*
  7264. * Parse the attribute wildcard.
  7265. */
  7266. if (IS_SCHEMA(child, "anyAttribute")) {
  7267. ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
  7268. schema, child);
  7269. child = child->next;
  7270. }
  7271. if (child != NULL) {
  7272. xmlSchemaPContentErr(pctxt,
  7273. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7274. NULL, node, child, NULL,
  7275. "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
  7276. }
  7277. return (ret);
  7278. }
  7279. /**
  7280. * xmlSchemaPValAttrFormDefault:
  7281. * @value: the value
  7282. * @flags: the flags to be modified
  7283. * @flagQualified: the specific flag for "qualified"
  7284. *
  7285. * Returns 0 if the value is valid, 1 otherwise.
  7286. */
  7287. static int
  7288. xmlSchemaPValAttrFormDefault(const xmlChar *value,
  7289. int *flags,
  7290. int flagQualified)
  7291. {
  7292. if (xmlStrEqual(value, BAD_CAST "qualified")) {
  7293. if ((*flags & flagQualified) == 0)
  7294. *flags |= flagQualified;
  7295. } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
  7296. return (1);
  7297. return (0);
  7298. }
  7299. /**
  7300. * xmlSchemaPValAttrBlockFinal:
  7301. * @value: the value
  7302. * @flags: the flags to be modified
  7303. * @flagAll: the specific flag for "#all"
  7304. * @flagExtension: the specific flag for "extension"
  7305. * @flagRestriction: the specific flag for "restriction"
  7306. * @flagSubstitution: the specific flag for "substitution"
  7307. * @flagList: the specific flag for "list"
  7308. * @flagUnion: the specific flag for "union"
  7309. *
  7310. * Validates the value of the attribute "final" and "block". The value
  7311. * is converted into the specified flag values and returned in @flags.
  7312. *
  7313. * Returns 0 if the value is valid, 1 otherwise.
  7314. */
  7315. static int
  7316. xmlSchemaPValAttrBlockFinal(const xmlChar *value,
  7317. int *flags,
  7318. int flagAll,
  7319. int flagExtension,
  7320. int flagRestriction,
  7321. int flagSubstitution,
  7322. int flagList,
  7323. int flagUnion)
  7324. {
  7325. int ret = 0;
  7326. /*
  7327. * TODO: This does not check for dublicate entries.
  7328. */
  7329. if ((flags == NULL) || (value == NULL))
  7330. return (-1);
  7331. if (value[0] == 0)
  7332. return (0);
  7333. if (xmlStrEqual(value, BAD_CAST "#all")) {
  7334. if (flagAll != -1)
  7335. *flags |= flagAll;
  7336. else {
  7337. if (flagExtension != -1)
  7338. *flags |= flagExtension;
  7339. if (flagRestriction != -1)
  7340. *flags |= flagRestriction;
  7341. if (flagSubstitution != -1)
  7342. *flags |= flagSubstitution;
  7343. if (flagList != -1)
  7344. *flags |= flagList;
  7345. if (flagUnion != -1)
  7346. *flags |= flagUnion;
  7347. }
  7348. } else {
  7349. const xmlChar *end, *cur = value;
  7350. xmlChar *item;
  7351. do {
  7352. while (IS_BLANK_CH(*cur))
  7353. cur++;
  7354. end = cur;
  7355. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  7356. end++;
  7357. if (end == cur)
  7358. break;
  7359. item = xmlStrndup(cur, end - cur);
  7360. if (xmlStrEqual(item, BAD_CAST "extension")) {
  7361. if (flagExtension != -1) {
  7362. if ((*flags & flagExtension) == 0)
  7363. *flags |= flagExtension;
  7364. } else
  7365. ret = 1;
  7366. } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
  7367. if (flagRestriction != -1) {
  7368. if ((*flags & flagRestriction) == 0)
  7369. *flags |= flagRestriction;
  7370. } else
  7371. ret = 1;
  7372. } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
  7373. if (flagSubstitution != -1) {
  7374. if ((*flags & flagSubstitution) == 0)
  7375. *flags |= flagSubstitution;
  7376. } else
  7377. ret = 1;
  7378. } else if (xmlStrEqual(item, BAD_CAST "list")) {
  7379. if (flagList != -1) {
  7380. if ((*flags & flagList) == 0)
  7381. *flags |= flagList;
  7382. } else
  7383. ret = 1;
  7384. } else if (xmlStrEqual(item, BAD_CAST "union")) {
  7385. if (flagUnion != -1) {
  7386. if ((*flags & flagUnion) == 0)
  7387. *flags |= flagUnion;
  7388. } else
  7389. ret = 1;
  7390. } else
  7391. ret = 1;
  7392. if (item != NULL)
  7393. xmlFree(item);
  7394. cur = end;
  7395. } while ((ret == 0) && (*cur != 0));
  7396. }
  7397. return (ret);
  7398. }
  7399. static int
  7400. xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
  7401. xmlSchemaIDCPtr idc,
  7402. xmlSchemaIDCSelectPtr selector,
  7403. xmlAttrPtr attr,
  7404. int isField)
  7405. {
  7406. xmlNodePtr node;
  7407. /*
  7408. * c-selector-xpath:
  7409. * Schema Component Constraint: Selector Value OK
  7410. *
  7411. * TODO: 1 The {selector} must be a valid XPath expression, as defined
  7412. * in [XPath].
  7413. */
  7414. if (selector == NULL) {
  7415. xmlSchemaPErr(ctxt, idc->node,
  7416. XML_SCHEMAP_INTERNAL,
  7417. "Internal error: xmlSchemaCheckCSelectorXPath, "
  7418. "the selector is not specified.\n", NULL, NULL);
  7419. return (-1);
  7420. }
  7421. if (attr == NULL)
  7422. node = idc->node;
  7423. else
  7424. node = (xmlNodePtr) attr;
  7425. if (selector->xpath == NULL) {
  7426. xmlSchemaPCustomErr(ctxt,
  7427. /* TODO: Adjust error code. */
  7428. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7429. NULL, node,
  7430. "The XPath expression of the selector is not valid", NULL);
  7431. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7432. } else {
  7433. const xmlChar **nsArray = NULL;
  7434. xmlNsPtr *nsList = NULL;
  7435. /*
  7436. * Compile the XPath expression.
  7437. */
  7438. /*
  7439. * TODO: We need the array of in-scope namespaces for compilation.
  7440. * TODO: Call xmlPatterncompile with different options for selector/
  7441. * field.
  7442. */
  7443. if (attr == NULL)
  7444. nsList = NULL;
  7445. else
  7446. nsList = xmlGetNsList(attr->doc, attr->parent);
  7447. /*
  7448. * Build an array of prefixes and namespaces.
  7449. */
  7450. if (nsList != NULL) {
  7451. int i, count = 0;
  7452. for (i = 0; nsList[i] != NULL; i++)
  7453. count++;
  7454. nsArray = (const xmlChar **) xmlMalloc(
  7455. (count * 2 + 1) * sizeof(const xmlChar *));
  7456. if (nsArray == NULL) {
  7457. xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
  7458. NULL);
  7459. xmlFree(nsList);
  7460. return (-1);
  7461. }
  7462. for (i = 0; i < count; i++) {
  7463. nsArray[2 * i] = nsList[i]->href;
  7464. nsArray[2 * i + 1] = nsList[i]->prefix;
  7465. }
  7466. nsArray[count * 2] = NULL;
  7467. xmlFree(nsList);
  7468. }
  7469. /*
  7470. * TODO: Differentiate between "selector" and "field".
  7471. */
  7472. if (isField)
  7473. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7474. NULL, XML_PATTERN_XSFIELD, nsArray);
  7475. else
  7476. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7477. NULL, XML_PATTERN_XSSEL, nsArray);
  7478. if (nsArray != NULL)
  7479. xmlFree((xmlChar **) nsArray);
  7480. if (selector->xpathComp == NULL) {
  7481. xmlSchemaPCustomErr(ctxt,
  7482. /* TODO: Adjust error code? */
  7483. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7484. NULL, node,
  7485. "The XPath expression '%s' could not be "
  7486. "compiled", selector->xpath);
  7487. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7488. }
  7489. }
  7490. return (0);
  7491. }
  7492. #define ADD_ANNOTATION(annot) \
  7493. xmlSchemaAnnotPtr cur = item->annot; \
  7494. if (item->annot == NULL) { \
  7495. item->annot = annot; \
  7496. return (annot); \
  7497. } \
  7498. cur = item->annot; \
  7499. if (cur->next != NULL) { \
  7500. cur = cur->next; \
  7501. } \
  7502. cur->next = annot;
  7503. /**
  7504. * xmlSchemaAssignAnnotation:
  7505. * @item: the schema component
  7506. * @annot: the annotation
  7507. *
  7508. * Adds the annotation to the given schema component.
  7509. *
  7510. * Returns the given annotaion.
  7511. */
  7512. static xmlSchemaAnnotPtr
  7513. xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
  7514. xmlSchemaAnnotPtr annot)
  7515. {
  7516. if ((annItem == NULL) || (annot == NULL))
  7517. return (NULL);
  7518. switch (annItem->type) {
  7519. case XML_SCHEMA_TYPE_ELEMENT: {
  7520. xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
  7521. ADD_ANNOTATION(annot)
  7522. }
  7523. break;
  7524. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  7525. xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
  7526. ADD_ANNOTATION(annot)
  7527. }
  7528. break;
  7529. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  7530. case XML_SCHEMA_TYPE_ANY: {
  7531. xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
  7532. ADD_ANNOTATION(annot)
  7533. }
  7534. break;
  7535. case XML_SCHEMA_TYPE_PARTICLE:
  7536. case XML_SCHEMA_TYPE_IDC_KEY:
  7537. case XML_SCHEMA_TYPE_IDC_KEYREF:
  7538. case XML_SCHEMA_TYPE_IDC_UNIQUE: {
  7539. xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
  7540. ADD_ANNOTATION(annot)
  7541. }
  7542. break;
  7543. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
  7544. xmlSchemaAttributeGroupPtr item =
  7545. (xmlSchemaAttributeGroupPtr) annItem;
  7546. ADD_ANNOTATION(annot)
  7547. }
  7548. break;
  7549. case XML_SCHEMA_TYPE_NOTATION: {
  7550. xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
  7551. ADD_ANNOTATION(annot)
  7552. }
  7553. break;
  7554. case XML_SCHEMA_FACET_MININCLUSIVE:
  7555. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  7556. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  7557. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  7558. case XML_SCHEMA_FACET_TOTALDIGITS:
  7559. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  7560. case XML_SCHEMA_FACET_PATTERN:
  7561. case XML_SCHEMA_FACET_ENUMERATION:
  7562. case XML_SCHEMA_FACET_WHITESPACE:
  7563. case XML_SCHEMA_FACET_LENGTH:
  7564. case XML_SCHEMA_FACET_MAXLENGTH:
  7565. case XML_SCHEMA_FACET_MINLENGTH: {
  7566. xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
  7567. ADD_ANNOTATION(annot)
  7568. }
  7569. break;
  7570. case XML_SCHEMA_TYPE_SIMPLE:
  7571. case XML_SCHEMA_TYPE_COMPLEX: {
  7572. xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
  7573. ADD_ANNOTATION(annot)
  7574. }
  7575. break;
  7576. case XML_SCHEMA_TYPE_GROUP: {
  7577. xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
  7578. ADD_ANNOTATION(annot)
  7579. }
  7580. break;
  7581. case XML_SCHEMA_TYPE_SEQUENCE:
  7582. case XML_SCHEMA_TYPE_CHOICE:
  7583. case XML_SCHEMA_TYPE_ALL: {
  7584. xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
  7585. ADD_ANNOTATION(annot)
  7586. }
  7587. break;
  7588. default:
  7589. xmlSchemaPCustomErr(NULL,
  7590. XML_SCHEMAP_INTERNAL,
  7591. NULL, NULL,
  7592. "Internal error: xmlSchemaAddAnnotation, "
  7593. "The item is not a annotated schema component", NULL);
  7594. break;
  7595. }
  7596. return (annot);
  7597. }
  7598. /**
  7599. * xmlSchemaParseIDCSelectorAndField:
  7600. * @ctxt: a schema validation context
  7601. * @schema: the schema being built
  7602. * @node: a subtree containing XML Schema informations
  7603. *
  7604. * Parses a XML Schema identity-contraint definition's
  7605. * <selector> and <field> elements.
  7606. *
  7607. * Returns the parsed identity-constraint definition.
  7608. */
  7609. static xmlSchemaIDCSelectPtr
  7610. xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
  7611. xmlSchemaIDCPtr idc,
  7612. xmlNodePtr node,
  7613. int isField)
  7614. {
  7615. xmlSchemaIDCSelectPtr item;
  7616. xmlNodePtr child = NULL;
  7617. xmlAttrPtr attr;
  7618. /*
  7619. * Check for illegal attributes.
  7620. */
  7621. attr = node->properties;
  7622. while (attr != NULL) {
  7623. if (attr->ns == NULL) {
  7624. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7625. (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
  7626. xmlSchemaPIllegalAttrErr(ctxt,
  7627. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7628. }
  7629. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7630. xmlSchemaPIllegalAttrErr(ctxt,
  7631. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7632. }
  7633. attr = attr->next;
  7634. }
  7635. /*
  7636. * Create the item.
  7637. */
  7638. item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
  7639. if (item == NULL) {
  7640. xmlSchemaPErrMemory(ctxt,
  7641. "allocating a 'selector' of an identity-constraint definition",
  7642. NULL);
  7643. return (NULL);
  7644. }
  7645. memset(item, 0, sizeof(xmlSchemaIDCSelect));
  7646. /*
  7647. * Attribute "xpath" (mandatory).
  7648. */
  7649. attr = xmlSchemaGetPropNode(node, "xpath");
  7650. if (attr == NULL) {
  7651. xmlSchemaPMissingAttrErr(ctxt,
  7652. XML_SCHEMAP_S4S_ATTR_MISSING,
  7653. NULL, node,
  7654. "name", NULL);
  7655. } else {
  7656. item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7657. /*
  7658. * URGENT TODO: "field"s have an other syntax than "selector"s.
  7659. */
  7660. if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
  7661. isField) == -1) {
  7662. xmlSchemaPErr(ctxt,
  7663. (xmlNodePtr) attr,
  7664. XML_SCHEMAP_INTERNAL,
  7665. "Internal error: xmlSchemaParseIDCSelectorAndField, "
  7666. "validating the XPath expression of a IDC selector.\n",
  7667. NULL, NULL);
  7668. }
  7669. }
  7670. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7671. /*
  7672. * And now for the children...
  7673. */
  7674. child = node->children;
  7675. if (IS_SCHEMA(child, "annotation")) {
  7676. /*
  7677. * Add the annotation to the parent IDC.
  7678. */
  7679. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
  7680. xmlSchemaParseAnnotation(ctxt, child, 1));
  7681. child = child->next;
  7682. }
  7683. if (child != NULL) {
  7684. xmlSchemaPContentErr(ctxt,
  7685. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7686. NULL, node, child,
  7687. NULL, "(annotation?)");
  7688. }
  7689. return (item);
  7690. }
  7691. /**
  7692. * xmlSchemaParseIDC:
  7693. * @ctxt: a schema validation context
  7694. * @schema: the schema being built
  7695. * @node: a subtree containing XML Schema informations
  7696. *
  7697. * Parses a XML Schema identity-contraint definition.
  7698. *
  7699. * Returns the parsed identity-constraint definition.
  7700. */
  7701. static xmlSchemaIDCPtr
  7702. xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
  7703. xmlSchemaPtr schema,
  7704. xmlNodePtr node,
  7705. xmlSchemaTypeType idcCategory,
  7706. const xmlChar *targetNamespace)
  7707. {
  7708. xmlSchemaIDCPtr item = NULL;
  7709. xmlNodePtr child = NULL;
  7710. xmlAttrPtr attr;
  7711. const xmlChar *name = NULL;
  7712. xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
  7713. /*
  7714. * Check for illegal attributes.
  7715. */
  7716. attr = node->properties;
  7717. while (attr != NULL) {
  7718. if (attr->ns == NULL) {
  7719. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7720. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7721. ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
  7722. (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
  7723. xmlSchemaPIllegalAttrErr(ctxt,
  7724. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7725. }
  7726. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7727. xmlSchemaPIllegalAttrErr(ctxt,
  7728. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7729. }
  7730. attr = attr->next;
  7731. }
  7732. /*
  7733. * Attribute "name" (mandatory).
  7734. */
  7735. attr = xmlSchemaGetPropNode(node, "name");
  7736. if (attr == NULL) {
  7737. xmlSchemaPMissingAttrErr(ctxt,
  7738. XML_SCHEMAP_S4S_ATTR_MISSING,
  7739. NULL, node,
  7740. "name", NULL);
  7741. return (NULL);
  7742. } else if (xmlSchemaPValAttrNode(ctxt,
  7743. NULL, attr,
  7744. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7745. return (NULL);
  7746. }
  7747. /* Create the component. */
  7748. item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
  7749. idcCategory, node);
  7750. if (item == NULL)
  7751. return(NULL);
  7752. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7753. if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
  7754. /*
  7755. * Attribute "refer" (mandatory).
  7756. */
  7757. attr = xmlSchemaGetPropNode(node, "refer");
  7758. if (attr == NULL) {
  7759. xmlSchemaPMissingAttrErr(ctxt,
  7760. XML_SCHEMAP_S4S_ATTR_MISSING,
  7761. NULL, node,
  7762. "refer", NULL);
  7763. } else {
  7764. /*
  7765. * Create a reference item.
  7766. */
  7767. item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
  7768. NULL, NULL);
  7769. if (item->ref == NULL)
  7770. return (NULL);
  7771. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7772. NULL, attr,
  7773. &(item->ref->targetNamespace),
  7774. &(item->ref->name));
  7775. xmlSchemaCheckReference(ctxt, schema, node, attr,
  7776. item->ref->targetNamespace);
  7777. }
  7778. }
  7779. /*
  7780. * And now for the children...
  7781. */
  7782. child = node->children;
  7783. if (IS_SCHEMA(child, "annotation")) {
  7784. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7785. child = child->next;
  7786. }
  7787. if (child == NULL) {
  7788. xmlSchemaPContentErr(ctxt,
  7789. XML_SCHEMAP_S4S_ELEM_MISSING,
  7790. NULL, node, child,
  7791. "A child element is missing",
  7792. "(annotation?, (selector, field+))");
  7793. }
  7794. /*
  7795. * Child element <selector>.
  7796. */
  7797. if (IS_SCHEMA(child, "selector")) {
  7798. item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
  7799. item, child, 0);
  7800. child = child->next;
  7801. /*
  7802. * Child elements <field>.
  7803. */
  7804. if (IS_SCHEMA(child, "field")) {
  7805. do {
  7806. field = xmlSchemaParseIDCSelectorAndField(ctxt,
  7807. item, child, 1);
  7808. if (field != NULL) {
  7809. field->index = item->nbFields;
  7810. item->nbFields++;
  7811. if (lastField != NULL)
  7812. lastField->next = field;
  7813. else
  7814. item->fields = field;
  7815. lastField = field;
  7816. }
  7817. child = child->next;
  7818. } while (IS_SCHEMA(child, "field"));
  7819. } else {
  7820. xmlSchemaPContentErr(ctxt,
  7821. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7822. NULL, node, child,
  7823. NULL, "(annotation?, (selector, field+))");
  7824. }
  7825. }
  7826. if (child != NULL) {
  7827. xmlSchemaPContentErr(ctxt,
  7828. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7829. NULL, node, child,
  7830. NULL, "(annotation?, (selector, field+))");
  7831. }
  7832. return (item);
  7833. }
  7834. /**
  7835. * xmlSchemaParseElement:
  7836. * @ctxt: a schema validation context
  7837. * @schema: the schema being built
  7838. * @node: a subtree containing XML Schema informations
  7839. * @topLevel: indicates if this is global declaration
  7840. *
  7841. * Parses a XML schema element declaration.
  7842. * *WARNING* this interface is highly subject to change
  7843. *
  7844. * Returns the element declaration or a particle; NULL in case
  7845. * of an error or if the particle has minOccurs==maxOccurs==0.
  7846. */
  7847. static xmlSchemaBasicItemPtr
  7848. xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  7849. xmlNodePtr node, int *isElemRef, int topLevel)
  7850. {
  7851. xmlSchemaElementPtr decl = NULL;
  7852. xmlSchemaParticlePtr particle = NULL;
  7853. xmlSchemaAnnotPtr annot = NULL;
  7854. xmlNodePtr child = NULL;
  7855. xmlAttrPtr attr, nameAttr;
  7856. int min, max, isRef = 0;
  7857. xmlChar *des = NULL;
  7858. /* 3.3.3 Constraints on XML Representations of Element Declarations */
  7859. /* TODO: Complete implementation of 3.3.6 */
  7860. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  7861. return (NULL);
  7862. if (isElemRef != NULL)
  7863. *isElemRef = 0;
  7864. /*
  7865. * If we get a "ref" attribute on a local <element> we will assume it's
  7866. * a reference - even if there's a "name" attribute; this seems to be more
  7867. * robust.
  7868. */
  7869. nameAttr = xmlSchemaGetPropNode(node, "name");
  7870. attr = xmlSchemaGetPropNode(node, "ref");
  7871. if ((topLevel) || (attr == NULL)) {
  7872. if (nameAttr == NULL) {
  7873. xmlSchemaPMissingAttrErr(ctxt,
  7874. XML_SCHEMAP_S4S_ATTR_MISSING,
  7875. NULL, node, "name", NULL);
  7876. return (NULL);
  7877. }
  7878. } else
  7879. isRef = 1;
  7880. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7881. child = node->children;
  7882. if (IS_SCHEMA(child, "annotation")) {
  7883. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7884. child = child->next;
  7885. }
  7886. /*
  7887. * Skip particle part if a global declaration.
  7888. */
  7889. if (topLevel)
  7890. goto declaration_part;
  7891. /*
  7892. * The particle part ==================================================
  7893. */
  7894. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  7895. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
  7896. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  7897. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  7898. if (particle == NULL)
  7899. goto return_null;
  7900. /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
  7901. if (isRef) {
  7902. const xmlChar *refNs = NULL, *ref = NULL;
  7903. xmlSchemaQNameRefPtr refer = NULL;
  7904. /*
  7905. * The reference part =============================================
  7906. */
  7907. if (isElemRef != NULL)
  7908. *isElemRef = 1;
  7909. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7910. NULL, attr, &refNs, &ref);
  7911. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  7912. /*
  7913. * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
  7914. */
  7915. if (nameAttr != NULL) {
  7916. xmlSchemaPMutualExclAttrErr(ctxt,
  7917. XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
  7918. }
  7919. /*
  7920. * Check for illegal attributes.
  7921. */
  7922. attr = node->properties;
  7923. while (attr != NULL) {
  7924. if (attr->ns == NULL) {
  7925. if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
  7926. xmlStrEqual(attr->name, BAD_CAST "name") ||
  7927. xmlStrEqual(attr->name, BAD_CAST "id") ||
  7928. xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
  7929. xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
  7930. {
  7931. attr = attr->next;
  7932. continue;
  7933. } else {
  7934. /* SPEC (3.3.3 : 2.2) */
  7935. xmlSchemaPCustomAttrErr(ctxt,
  7936. XML_SCHEMAP_SRC_ELEMENT_2_2,
  7937. NULL, NULL, attr,
  7938. "Only the attributes 'minOccurs', 'maxOccurs' and "
  7939. "'id' are allowed in addition to 'ref'");
  7940. break;
  7941. }
  7942. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7943. xmlSchemaPIllegalAttrErr(ctxt,
  7944. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7945. }
  7946. attr = attr->next;
  7947. }
  7948. /*
  7949. * No children except <annotation> expected.
  7950. */
  7951. if (child != NULL) {
  7952. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7953. NULL, node, child, NULL, "(annotation?)");
  7954. }
  7955. if ((min == 0) && (max == 0))
  7956. goto return_null;
  7957. /*
  7958. * Create the reference item and attach it to the particle.
  7959. */
  7960. refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
  7961. ref, refNs);
  7962. if (refer == NULL)
  7963. goto return_null;
  7964. particle->children = (xmlSchemaTreeItemPtr) refer;
  7965. particle->annot = annot;
  7966. /*
  7967. * Add the particle to pending components, since the reference
  7968. * need to be resolved.
  7969. */
  7970. WXS_ADD_PENDING(ctxt, particle);
  7971. return ((xmlSchemaBasicItemPtr) particle);
  7972. }
  7973. /*
  7974. * The declaration part ===============================================
  7975. */
  7976. declaration_part:
  7977. {
  7978. const xmlChar *ns = NULL, *fixed, *name, *attrValue;
  7979. xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
  7980. if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
  7981. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
  7982. goto return_null;
  7983. /*
  7984. * Evaluate the target namespace.
  7985. */
  7986. if (topLevel) {
  7987. ns = ctxt->targetNamespace;
  7988. } else {
  7989. attr = xmlSchemaGetPropNode(node, "form");
  7990. if (attr != NULL) {
  7991. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7992. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  7993. ns = ctxt->targetNamespace;
  7994. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
  7995. xmlSchemaPSimpleTypeErr(ctxt,
  7996. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7997. NULL, (xmlNodePtr) attr,
  7998. NULL, "(qualified | unqualified)",
  7999. attrValue, NULL, NULL, NULL);
  8000. }
  8001. } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8002. ns = ctxt->targetNamespace;
  8003. }
  8004. decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
  8005. if (decl == NULL) {
  8006. goto return_null;
  8007. }
  8008. /*
  8009. * Check for illegal attributes.
  8010. */
  8011. attr = node->properties;
  8012. while (attr != NULL) {
  8013. if (attr->ns == NULL) {
  8014. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8015. (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
  8016. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8017. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  8018. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  8019. (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
  8020. (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
  8021. {
  8022. if (topLevel == 0) {
  8023. if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  8024. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8025. (!xmlStrEqual(attr->name, BAD_CAST "form")))
  8026. {
  8027. xmlSchemaPIllegalAttrErr(ctxt,
  8028. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8029. }
  8030. } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
  8031. (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
  8032. (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
  8033. xmlSchemaPIllegalAttrErr(ctxt,
  8034. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8035. }
  8036. }
  8037. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8038. xmlSchemaPIllegalAttrErr(ctxt,
  8039. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8040. }
  8041. attr = attr->next;
  8042. }
  8043. /*
  8044. * Extract/validate attributes.
  8045. */
  8046. if (topLevel) {
  8047. /*
  8048. * Process top attributes of global element declarations here.
  8049. */
  8050. decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
  8051. decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
  8052. xmlSchemaPValAttrQName(ctxt, schema,
  8053. NULL, node, "substitutionGroup",
  8054. &(decl->substGroupNs), &(decl->substGroup));
  8055. if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
  8056. decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
  8057. /*
  8058. * Attribute "final".
  8059. */
  8060. attr = xmlSchemaGetPropNode(node, "final");
  8061. if (attr == NULL) {
  8062. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8063. decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
  8064. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8065. decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
  8066. } else {
  8067. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8068. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8069. -1,
  8070. XML_SCHEMAS_ELEM_FINAL_EXTENSION,
  8071. XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
  8072. xmlSchemaPSimpleTypeErr(ctxt,
  8073. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8074. NULL, (xmlNodePtr) attr,
  8075. NULL, "(#all | List of (extension | restriction))",
  8076. attrValue, NULL, NULL, NULL);
  8077. }
  8078. }
  8079. }
  8080. /*
  8081. * Attribute "block".
  8082. */
  8083. attr = xmlSchemaGetPropNode(node, "block");
  8084. if (attr == NULL) {
  8085. /*
  8086. * Apply default "block" values.
  8087. */
  8088. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8089. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
  8090. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8091. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
  8092. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8093. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
  8094. } else {
  8095. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8096. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8097. -1,
  8098. XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
  8099. XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
  8100. XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
  8101. xmlSchemaPSimpleTypeErr(ctxt,
  8102. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8103. NULL, (xmlNodePtr) attr,
  8104. NULL, "(#all | List of (extension | "
  8105. "restriction | substitution))", attrValue,
  8106. NULL, NULL, NULL);
  8107. }
  8108. }
  8109. if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
  8110. decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
  8111. attr = xmlSchemaGetPropNode(node, "type");
  8112. if (attr != NULL) {
  8113. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8114. NULL, attr,
  8115. &(decl->namedTypeNs), &(decl->namedType));
  8116. xmlSchemaCheckReference(ctxt, schema, node,
  8117. attr, decl->namedTypeNs);
  8118. }
  8119. decl->value = xmlSchemaGetProp(ctxt, node, "default");
  8120. attr = xmlSchemaGetPropNode(node, "fixed");
  8121. if (attr != NULL) {
  8122. fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8123. if (decl->value != NULL) {
  8124. /*
  8125. * 3.3.3 : 1
  8126. * default and fixed must not both be present.
  8127. */
  8128. xmlSchemaPMutualExclAttrErr(ctxt,
  8129. XML_SCHEMAP_SRC_ELEMENT_1,
  8130. NULL, attr, "default", "fixed");
  8131. } else {
  8132. decl->flags |= XML_SCHEMAS_ELEM_FIXED;
  8133. decl->value = fixed;
  8134. }
  8135. }
  8136. /*
  8137. * And now for the children...
  8138. */
  8139. if (IS_SCHEMA(child, "complexType")) {
  8140. /*
  8141. * 3.3.3 : 3
  8142. * "type" and either <simpleType> or <complexType> are mutually
  8143. * exclusive
  8144. */
  8145. if (decl->namedType != NULL) {
  8146. xmlSchemaPContentErr(ctxt,
  8147. XML_SCHEMAP_SRC_ELEMENT_3,
  8148. NULL, node, child,
  8149. "The attribute 'type' and the <complexType> child are "
  8150. "mutually exclusive", NULL);
  8151. } else
  8152. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
  8153. child = child->next;
  8154. } else if (IS_SCHEMA(child, "simpleType")) {
  8155. /*
  8156. * 3.3.3 : 3
  8157. * "type" and either <simpleType> or <complexType> are
  8158. * mutually exclusive
  8159. */
  8160. if (decl->namedType != NULL) {
  8161. xmlSchemaPContentErr(ctxt,
  8162. XML_SCHEMAP_SRC_ELEMENT_3,
  8163. NULL, node, child,
  8164. "The attribute 'type' and the <simpleType> child are "
  8165. "mutually exclusive", NULL);
  8166. } else
  8167. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8168. child = child->next;
  8169. }
  8170. while ((IS_SCHEMA(child, "unique")) ||
  8171. (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
  8172. if (IS_SCHEMA(child, "unique")) {
  8173. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8174. XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
  8175. } else if (IS_SCHEMA(child, "key")) {
  8176. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8177. XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
  8178. } else if (IS_SCHEMA(child, "keyref")) {
  8179. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8180. XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
  8181. }
  8182. if (lastIDC != NULL)
  8183. lastIDC->next = curIDC;
  8184. else
  8185. decl->idcs = (void *) curIDC;
  8186. lastIDC = curIDC;
  8187. child = child->next;
  8188. }
  8189. if (child != NULL) {
  8190. xmlSchemaPContentErr(ctxt,
  8191. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8192. NULL, node, child,
  8193. NULL, "(annotation?, ((simpleType | complexType)?, "
  8194. "(unique | key | keyref)*))");
  8195. }
  8196. decl->annot = annot;
  8197. }
  8198. /*
  8199. * NOTE: Element Declaration Representation OK 4. will be checked at a
  8200. * different layer.
  8201. */
  8202. FREE_AND_NULL(des)
  8203. if (topLevel)
  8204. return ((xmlSchemaBasicItemPtr) decl);
  8205. else {
  8206. particle->children = (xmlSchemaTreeItemPtr) decl;
  8207. return ((xmlSchemaBasicItemPtr) particle);
  8208. }
  8209. return_null:
  8210. FREE_AND_NULL(des);
  8211. if (annot != NULL) {
  8212. if (particle != NULL)
  8213. particle->annot = NULL;
  8214. if (decl != NULL)
  8215. decl->annot = NULL;
  8216. xmlSchemaFreeAnnot(annot);
  8217. }
  8218. return (NULL);
  8219. }
  8220. /**
  8221. * xmlSchemaParseUnion:
  8222. * @ctxt: a schema validation context
  8223. * @schema: the schema being built
  8224. * @node: a subtree containing XML Schema informations
  8225. *
  8226. * parse a XML schema Union definition
  8227. * *WARNING* this interface is highly subject to change
  8228. *
  8229. * Returns -1 in case of internal error, 0 in case of success and a positive
  8230. * error code otherwise.
  8231. */
  8232. static int
  8233. xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8234. xmlNodePtr node)
  8235. {
  8236. xmlSchemaTypePtr type;
  8237. xmlNodePtr child = NULL;
  8238. xmlAttrPtr attr;
  8239. const xmlChar *cur = NULL;
  8240. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8241. return (-1);
  8242. /* Not a component, don't create it. */
  8243. type = ctxt->ctxtType;
  8244. /*
  8245. * Mark the simple type as being of variety "union".
  8246. */
  8247. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  8248. /*
  8249. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8250. * then the �simple ur-type definition�."
  8251. */
  8252. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8253. /*
  8254. * Check for illegal attributes.
  8255. */
  8256. attr = node->properties;
  8257. while (attr != NULL) {
  8258. if (attr->ns == NULL) {
  8259. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8260. (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
  8261. xmlSchemaPIllegalAttrErr(ctxt,
  8262. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8263. }
  8264. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8265. xmlSchemaPIllegalAttrErr(ctxt,
  8266. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8267. }
  8268. attr = attr->next;
  8269. }
  8270. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8271. /*
  8272. * Attribute "memberTypes". This is a list of QNames.
  8273. * TODO: Check the value to contain anything.
  8274. */
  8275. attr = xmlSchemaGetPropNode(node, "memberTypes");
  8276. if (attr != NULL) {
  8277. const xmlChar *end;
  8278. xmlChar *tmp;
  8279. const xmlChar *localName, *nsName;
  8280. xmlSchemaTypeLinkPtr link, lastLink = NULL;
  8281. xmlSchemaQNameRefPtr ref;
  8282. cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8283. type->base = cur;
  8284. do {
  8285. while (IS_BLANK_CH(*cur))
  8286. cur++;
  8287. end = cur;
  8288. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  8289. end++;
  8290. if (end == cur)
  8291. break;
  8292. tmp = xmlStrndup(cur, end - cur);
  8293. if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  8294. NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
  8295. /*
  8296. * Create the member type link.
  8297. */
  8298. link = (xmlSchemaTypeLinkPtr)
  8299. xmlMalloc(sizeof(xmlSchemaTypeLink));
  8300. if (link == NULL) {
  8301. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8302. "allocating a type link", NULL);
  8303. return (-1);
  8304. }
  8305. link->type = NULL;
  8306. link->next = NULL;
  8307. if (lastLink == NULL)
  8308. type->memberTypes = link;
  8309. else
  8310. lastLink->next = link;
  8311. lastLink = link;
  8312. /*
  8313. * Create a reference item.
  8314. */
  8315. ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
  8316. localName, nsName);
  8317. if (ref == NULL) {
  8318. FREE_AND_NULL(tmp)
  8319. return (-1);
  8320. }
  8321. /*
  8322. * Assign the reference to the link, it will be resolved
  8323. * later during fixup of the union simple type.
  8324. */
  8325. link->type = (xmlSchemaTypePtr) ref;
  8326. }
  8327. FREE_AND_NULL(tmp)
  8328. cur = end;
  8329. } while (*cur != 0);
  8330. }
  8331. /*
  8332. * And now for the children...
  8333. */
  8334. child = node->children;
  8335. if (IS_SCHEMA(child, "annotation")) {
  8336. /*
  8337. * Add the annotation to the simple type ancestor.
  8338. */
  8339. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8340. xmlSchemaParseAnnotation(ctxt, child, 1));
  8341. child = child->next;
  8342. }
  8343. if (IS_SCHEMA(child, "simpleType")) {
  8344. xmlSchemaTypePtr subtype, last = NULL;
  8345. /*
  8346. * Anchor the member types in the "subtypes" field of the
  8347. * simple type.
  8348. */
  8349. while (IS_SCHEMA(child, "simpleType")) {
  8350. subtype = (xmlSchemaTypePtr)
  8351. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8352. if (subtype != NULL) {
  8353. if (last == NULL) {
  8354. type->subtypes = subtype;
  8355. last = subtype;
  8356. } else {
  8357. last->next = subtype;
  8358. last = subtype;
  8359. }
  8360. last->next = NULL;
  8361. }
  8362. child = child->next;
  8363. }
  8364. }
  8365. if (child != NULL) {
  8366. xmlSchemaPContentErr(ctxt,
  8367. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8368. NULL, node, child, NULL, "(annotation?, simpleType*)");
  8369. }
  8370. if ((attr == NULL) && (type->subtypes == NULL)) {
  8371. /*
  8372. * src-union-memberTypes-or-simpleTypes
  8373. * Either the memberTypes [attribute] of the <union> element must
  8374. * be non-empty or there must be at least one simpleType [child].
  8375. */
  8376. xmlSchemaPCustomErr(ctxt,
  8377. XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
  8378. NULL, node,
  8379. "Either the attribute 'memberTypes' or "
  8380. "at least one <simpleType> child must be present", NULL);
  8381. }
  8382. return (0);
  8383. }
  8384. /**
  8385. * xmlSchemaParseList:
  8386. * @ctxt: a schema validation context
  8387. * @schema: the schema being built
  8388. * @node: a subtree containing XML Schema informations
  8389. *
  8390. * parse a XML schema List definition
  8391. * *WARNING* this interface is highly subject to change
  8392. *
  8393. * Returns -1 in case of error, 0 if the declaration is improper and
  8394. * 1 in case of success.
  8395. */
  8396. static xmlSchemaTypePtr
  8397. xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8398. xmlNodePtr node)
  8399. {
  8400. xmlSchemaTypePtr type;
  8401. xmlNodePtr child = NULL;
  8402. xmlAttrPtr attr;
  8403. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8404. return (NULL);
  8405. /* Not a component, don't create it. */
  8406. type = ctxt->ctxtType;
  8407. /*
  8408. * Mark the type as being of variety "list".
  8409. */
  8410. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  8411. /*
  8412. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8413. * then the �simple ur-type definition�."
  8414. */
  8415. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8416. /*
  8417. * Check for illegal attributes.
  8418. */
  8419. attr = node->properties;
  8420. while (attr != NULL) {
  8421. if (attr->ns == NULL) {
  8422. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8423. (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
  8424. xmlSchemaPIllegalAttrErr(ctxt,
  8425. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8426. }
  8427. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8428. xmlSchemaPIllegalAttrErr(ctxt,
  8429. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8430. }
  8431. attr = attr->next;
  8432. }
  8433. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8434. /*
  8435. * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
  8436. * fields for holding the reference to the itemType.
  8437. *
  8438. * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
  8439. * the "ref" fields.
  8440. */
  8441. xmlSchemaPValAttrQName(ctxt, schema, NULL,
  8442. node, "itemType", &(type->baseNs), &(type->base));
  8443. /*
  8444. * And now for the children...
  8445. */
  8446. child = node->children;
  8447. if (IS_SCHEMA(child, "annotation")) {
  8448. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8449. xmlSchemaParseAnnotation(ctxt, child, 1));
  8450. child = child->next;
  8451. }
  8452. if (IS_SCHEMA(child, "simpleType")) {
  8453. /*
  8454. * src-list-itemType-or-simpleType
  8455. * Either the itemType [attribute] or the <simpleType> [child] of
  8456. * the <list> element must be present, but not both.
  8457. */
  8458. if (type->base != NULL) {
  8459. xmlSchemaPCustomErr(ctxt,
  8460. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8461. NULL, node,
  8462. "The attribute 'itemType' and the <simpleType> child "
  8463. "are mutually exclusive", NULL);
  8464. } else {
  8465. type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8466. }
  8467. child = child->next;
  8468. } else if (type->base == NULL) {
  8469. xmlSchemaPCustomErr(ctxt,
  8470. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8471. NULL, node,
  8472. "Either the attribute 'itemType' or the <simpleType> child "
  8473. "must be present", NULL);
  8474. }
  8475. if (child != NULL) {
  8476. xmlSchemaPContentErr(ctxt,
  8477. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8478. NULL, node, child, NULL, "(annotation?, simpleType?)");
  8479. }
  8480. if ((type->base == NULL) &&
  8481. (type->subtypes == NULL) &&
  8482. (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
  8483. xmlSchemaPCustomErr(ctxt,
  8484. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8485. NULL, node,
  8486. "Either the attribute 'itemType' or the <simpleType> child "
  8487. "must be present", NULL);
  8488. }
  8489. return (NULL);
  8490. }
  8491. /**
  8492. * xmlSchemaParseSimpleType:
  8493. * @ctxt: a schema validation context
  8494. * @schema: the schema being built
  8495. * @node: a subtree containing XML Schema informations
  8496. *
  8497. * parse a XML schema Simple Type definition
  8498. * *WARNING* this interface is highly subject to change
  8499. *
  8500. * Returns -1 in case of error, 0 if the declaration is improper and
  8501. * 1 in case of success.
  8502. */
  8503. static xmlSchemaTypePtr
  8504. xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8505. xmlNodePtr node, int topLevel)
  8506. {
  8507. xmlSchemaTypePtr type, oldCtxtType;
  8508. xmlNodePtr child = NULL;
  8509. const xmlChar *attrValue = NULL;
  8510. xmlAttrPtr attr;
  8511. int hasRestriction = 0;
  8512. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8513. return (NULL);
  8514. if (topLevel) {
  8515. attr = xmlSchemaGetPropNode(node, "name");
  8516. if (attr == NULL) {
  8517. xmlSchemaPMissingAttrErr(ctxt,
  8518. XML_SCHEMAP_S4S_ATTR_MISSING,
  8519. NULL, node,
  8520. "name", NULL);
  8521. return (NULL);
  8522. } else {
  8523. if (xmlSchemaPValAttrNode(ctxt,
  8524. NULL, attr,
  8525. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
  8526. return (NULL);
  8527. /*
  8528. * Skip built-in types.
  8529. */
  8530. if (ctxt->isS4S) {
  8531. xmlSchemaTypePtr biType;
  8532. if (ctxt->isRedefine) {
  8533. /*
  8534. * REDEFINE: Disallow redefinition of built-in-types.
  8535. * TODO: It seems that the spec does not say anything
  8536. * about this case.
  8537. */
  8538. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8539. NULL, node,
  8540. "Redefinition of built-in simple types is not "
  8541. "supported", NULL);
  8542. return(NULL);
  8543. }
  8544. biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
  8545. if (biType != NULL)
  8546. return (biType);
  8547. }
  8548. }
  8549. }
  8550. /*
  8551. * TargetNamespace:
  8552. * SPEC "The �actual value� of the targetNamespace [attribute]
  8553. * of the <schema> ancestor element information item if present,
  8554. * otherwise �absent�.
  8555. */
  8556. if (topLevel == 0) {
  8557. #ifdef ENABLE_NAMED_LOCALS
  8558. char buf[40];
  8559. #endif
  8560. /*
  8561. * Parse as local simple type definition.
  8562. */
  8563. #ifdef ENABLE_NAMED_LOCALS
  8564. snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
  8565. type = xmlSchemaAddType(ctxt, schema,
  8566. XML_SCHEMA_TYPE_SIMPLE,
  8567. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  8568. ctxt->targetNamespace, node, 0);
  8569. #else
  8570. type = xmlSchemaAddType(ctxt, schema,
  8571. XML_SCHEMA_TYPE_SIMPLE,
  8572. NULL, ctxt->targetNamespace, node, 0);
  8573. #endif
  8574. if (type == NULL)
  8575. return (NULL);
  8576. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8577. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8578. /*
  8579. * Check for illegal attributes.
  8580. */
  8581. attr = node->properties;
  8582. while (attr != NULL) {
  8583. if (attr->ns == NULL) {
  8584. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  8585. xmlSchemaPIllegalAttrErr(ctxt,
  8586. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8587. }
  8588. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8589. xmlSchemaPIllegalAttrErr(ctxt,
  8590. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8591. }
  8592. attr = attr->next;
  8593. }
  8594. } else {
  8595. /*
  8596. * Parse as global simple type definition.
  8597. *
  8598. * Note that attrValue is the value of the attribute "name" here.
  8599. */
  8600. type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
  8601. attrValue, ctxt->targetNamespace, node, 1);
  8602. if (type == NULL)
  8603. return (NULL);
  8604. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8605. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8606. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  8607. /*
  8608. * Check for illegal attributes.
  8609. */
  8610. attr = node->properties;
  8611. while (attr != NULL) {
  8612. if (attr->ns == NULL) {
  8613. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8614. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8615. (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
  8616. xmlSchemaPIllegalAttrErr(ctxt,
  8617. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8618. }
  8619. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8620. xmlSchemaPIllegalAttrErr(ctxt,
  8621. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8622. }
  8623. attr = attr->next;
  8624. }
  8625. /*
  8626. * Attribute "final".
  8627. */
  8628. attr = xmlSchemaGetPropNode(node, "final");
  8629. if (attr == NULL) {
  8630. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8631. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  8632. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8633. type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
  8634. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8635. type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
  8636. } else {
  8637. attrValue = xmlSchemaGetProp(ctxt, node, "final");
  8638. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  8639. -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
  8640. XML_SCHEMAS_TYPE_FINAL_LIST,
  8641. XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
  8642. xmlSchemaPSimpleTypeErr(ctxt,
  8643. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8644. WXS_BASIC_CAST type, (xmlNodePtr) attr,
  8645. NULL, "(#all | List of (list | union | restriction)",
  8646. attrValue, NULL, NULL, NULL);
  8647. }
  8648. }
  8649. }
  8650. type->targetNamespace = ctxt->targetNamespace;
  8651. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8652. /*
  8653. * And now for the children...
  8654. */
  8655. oldCtxtType = ctxt->ctxtType;
  8656. ctxt->ctxtType = type;
  8657. child = node->children;
  8658. if (IS_SCHEMA(child, "annotation")) {
  8659. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8660. child = child->next;
  8661. }
  8662. if (child == NULL) {
  8663. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
  8664. NULL, node, child, NULL,
  8665. "(annotation?, (restriction | list | union))");
  8666. } else if (IS_SCHEMA(child, "restriction")) {
  8667. xmlSchemaParseRestriction(ctxt, schema, child,
  8668. XML_SCHEMA_TYPE_SIMPLE);
  8669. hasRestriction = 1;
  8670. child = child->next;
  8671. } else if (IS_SCHEMA(child, "list")) {
  8672. xmlSchemaParseList(ctxt, schema, child);
  8673. child = child->next;
  8674. } else if (IS_SCHEMA(child, "union")) {
  8675. xmlSchemaParseUnion(ctxt, schema, child);
  8676. child = child->next;
  8677. }
  8678. if (child != NULL) {
  8679. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8680. NULL, node, child, NULL,
  8681. "(annotation?, (restriction | list | union))");
  8682. }
  8683. /*
  8684. * REDEFINE: SPEC src-redefine (5)
  8685. * "Within the [children], each <simpleType> must have a
  8686. * <restriction> among its [children] ... the �actual value� of whose
  8687. * base [attribute] must be the same as the �actual value� of its own
  8688. * name attribute plus target namespace;"
  8689. */
  8690. if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
  8691. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8692. NULL, node, "This is a redefinition, thus the "
  8693. "<simpleType> must have a <restriction> child", NULL);
  8694. }
  8695. ctxt->ctxtType = oldCtxtType;
  8696. return (type);
  8697. }
  8698. /**
  8699. * xmlSchemaParseModelGroupDefRef:
  8700. * @ctxt: the parser context
  8701. * @schema: the schema being built
  8702. * @node: the node
  8703. *
  8704. * Parses a reference to a model group definition.
  8705. *
  8706. * We will return a particle component with a qname-component or
  8707. * NULL in case of an error.
  8708. */
  8709. static xmlSchemaTreeItemPtr
  8710. xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
  8711. xmlSchemaPtr schema,
  8712. xmlNodePtr node)
  8713. {
  8714. xmlSchemaParticlePtr item;
  8715. xmlNodePtr child = NULL;
  8716. xmlAttrPtr attr;
  8717. const xmlChar *ref = NULL, *refNs = NULL;
  8718. int min, max;
  8719. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8720. return (NULL);
  8721. attr = xmlSchemaGetPropNode(node, "ref");
  8722. if (attr == NULL) {
  8723. xmlSchemaPMissingAttrErr(ctxt,
  8724. XML_SCHEMAP_S4S_ATTR_MISSING,
  8725. NULL, node, "ref", NULL);
  8726. return (NULL);
  8727. } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
  8728. attr, &refNs, &ref) != 0) {
  8729. return (NULL);
  8730. }
  8731. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8732. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  8733. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  8734. "(xs:nonNegativeInteger | unbounded)");
  8735. /*
  8736. * Check for illegal attributes.
  8737. */
  8738. attr = node->properties;
  8739. while (attr != NULL) {
  8740. if (attr->ns == NULL) {
  8741. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  8742. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8743. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8744. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
  8745. xmlSchemaPIllegalAttrErr(ctxt,
  8746. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8747. }
  8748. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8749. xmlSchemaPIllegalAttrErr(ctxt,
  8750. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8751. }
  8752. attr = attr->next;
  8753. }
  8754. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8755. item = xmlSchemaAddParticle(ctxt, node, min, max);
  8756. if (item == NULL)
  8757. return (NULL);
  8758. /*
  8759. * Create a qname-reference and set as the term; it will be substituted
  8760. * for the model group after the reference has been resolved.
  8761. */
  8762. item->children = (xmlSchemaTreeItemPtr)
  8763. xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
  8764. xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
  8765. /*
  8766. * And now for the children...
  8767. */
  8768. child = node->children;
  8769. /* TODO: Is annotation even allowed for a model group reference? */
  8770. if (IS_SCHEMA(child, "annotation")) {
  8771. /*
  8772. * TODO: What to do exactly with the annotation?
  8773. */
  8774. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8775. child = child->next;
  8776. }
  8777. if (child != NULL) {
  8778. xmlSchemaPContentErr(ctxt,
  8779. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8780. NULL, node, child, NULL,
  8781. "(annotation?)");
  8782. }
  8783. /*
  8784. * Corresponds to no component at all if minOccurs==maxOccurs==0.
  8785. */
  8786. if ((min == 0) && (max == 0))
  8787. return (NULL);
  8788. return ((xmlSchemaTreeItemPtr) item);
  8789. }
  8790. /**
  8791. * xmlSchemaParseModelGroupDefinition:
  8792. * @ctxt: a schema validation context
  8793. * @schema: the schema being built
  8794. * @node: a subtree containing XML Schema informations
  8795. *
  8796. * Parses a XML schema model group definition.
  8797. *
  8798. * Note that the contraint src-redefine (6.2) can't be applied until
  8799. * references have been resolved. So we will do this at the
  8800. * component fixup level.
  8801. *
  8802. * *WARNING* this interface is highly subject to change
  8803. *
  8804. * Returns -1 in case of error, 0 if the declaration is improper and
  8805. * 1 in case of success.
  8806. */
  8807. static xmlSchemaModelGroupDefPtr
  8808. xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  8809. xmlSchemaPtr schema,
  8810. xmlNodePtr node)
  8811. {
  8812. xmlSchemaModelGroupDefPtr item;
  8813. xmlNodePtr child = NULL;
  8814. xmlAttrPtr attr;
  8815. const xmlChar *name;
  8816. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8817. return (NULL);
  8818. attr = xmlSchemaGetPropNode(node, "name");
  8819. if (attr == NULL) {
  8820. xmlSchemaPMissingAttrErr(ctxt,
  8821. XML_SCHEMAP_S4S_ATTR_MISSING,
  8822. NULL, node,
  8823. "name", NULL);
  8824. return (NULL);
  8825. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8826. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  8827. return (NULL);
  8828. }
  8829. item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
  8830. ctxt->targetNamespace, node);
  8831. if (item == NULL)
  8832. return (NULL);
  8833. /*
  8834. * Check for illegal attributes.
  8835. */
  8836. attr = node->properties;
  8837. while (attr != NULL) {
  8838. if (attr->ns == NULL) {
  8839. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8840. (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  8841. xmlSchemaPIllegalAttrErr(ctxt,
  8842. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8843. }
  8844. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8845. xmlSchemaPIllegalAttrErr(ctxt,
  8846. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8847. }
  8848. attr = attr->next;
  8849. }
  8850. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8851. /*
  8852. * And now for the children...
  8853. */
  8854. child = node->children;
  8855. if (IS_SCHEMA(child, "annotation")) {
  8856. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8857. child = child->next;
  8858. }
  8859. if (IS_SCHEMA(child, "all")) {
  8860. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8861. XML_SCHEMA_TYPE_ALL, 0);
  8862. child = child->next;
  8863. } else if (IS_SCHEMA(child, "choice")) {
  8864. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8865. XML_SCHEMA_TYPE_CHOICE, 0);
  8866. child = child->next;
  8867. } else if (IS_SCHEMA(child, "sequence")) {
  8868. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8869. XML_SCHEMA_TYPE_SEQUENCE, 0);
  8870. child = child->next;
  8871. }
  8872. if (child != NULL) {
  8873. xmlSchemaPContentErr(ctxt,
  8874. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8875. NULL, node, child, NULL,
  8876. "(annotation?, (all | choice | sequence)?)");
  8877. }
  8878. return (item);
  8879. }
  8880. /**
  8881. * xmlSchemaCleanupDoc:
  8882. * @ctxt: a schema validation context
  8883. * @node: the root of the document.
  8884. *
  8885. * removes unwanted nodes in a schemas document tree
  8886. */
  8887. static void
  8888. xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
  8889. {
  8890. xmlNodePtr delete, cur;
  8891. if ((ctxt == NULL) || (root == NULL)) return;
  8892. /*
  8893. * Remove all the blank text nodes
  8894. */
  8895. delete = NULL;
  8896. cur = root;
  8897. while (cur != NULL) {
  8898. if (delete != NULL) {
  8899. xmlUnlinkNode(delete);
  8900. xmlFreeNode(delete);
  8901. delete = NULL;
  8902. }
  8903. if (cur->type == XML_TEXT_NODE) {
  8904. if (IS_BLANK_NODE(cur)) {
  8905. if (xmlNodeGetSpacePreserve(cur) != 1) {
  8906. delete = cur;
  8907. }
  8908. }
  8909. } else if ((cur->type != XML_ELEMENT_NODE) &&
  8910. (cur->type != XML_CDATA_SECTION_NODE)) {
  8911. delete = cur;
  8912. goto skip_children;
  8913. }
  8914. /*
  8915. * Skip to next node
  8916. */
  8917. if (cur->children != NULL) {
  8918. if ((cur->children->type != XML_ENTITY_DECL) &&
  8919. (cur->children->type != XML_ENTITY_REF_NODE) &&
  8920. (cur->children->type != XML_ENTITY_NODE)) {
  8921. cur = cur->children;
  8922. continue;
  8923. }
  8924. }
  8925. skip_children:
  8926. if (cur->next != NULL) {
  8927. cur = cur->next;
  8928. continue;
  8929. }
  8930. do {
  8931. cur = cur->parent;
  8932. if (cur == NULL)
  8933. break;
  8934. if (cur == root) {
  8935. cur = NULL;
  8936. break;
  8937. }
  8938. if (cur->next != NULL) {
  8939. cur = cur->next;
  8940. break;
  8941. }
  8942. } while (cur != NULL);
  8943. }
  8944. if (delete != NULL) {
  8945. xmlUnlinkNode(delete);
  8946. xmlFreeNode(delete);
  8947. delete = NULL;
  8948. }
  8949. }
  8950. static void
  8951. xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
  8952. {
  8953. if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8954. schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
  8955. if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
  8956. schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
  8957. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8958. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
  8959. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8960. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
  8961. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8962. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
  8963. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8964. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
  8965. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8966. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
  8967. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8968. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
  8969. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8970. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
  8971. }
  8972. static int
  8973. xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
  8974. xmlSchemaPtr schema,
  8975. xmlNodePtr node)
  8976. {
  8977. xmlAttrPtr attr;
  8978. const xmlChar *val;
  8979. int res = 0, oldErrs = ctxt->nberrors;
  8980. /*
  8981. * Those flags should be moved to the parser context flags,
  8982. * since they are not visible at the component level. I.e.
  8983. * they are used if processing schema *documents* only.
  8984. */
  8985. res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8986. HFAILURE;
  8987. /*
  8988. * Since the version is of type xs:token, we won't bother to
  8989. * check it.
  8990. */
  8991. /* REMOVED:
  8992. attr = xmlSchemaGetPropNode(node, "version");
  8993. if (attr != NULL) {
  8994. res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
  8995. xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
  8996. HFAILURE;
  8997. }
  8998. */
  8999. attr = xmlSchemaGetPropNode(node, "targetNamespace");
  9000. if (attr != NULL) {
  9001. res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
  9002. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  9003. HFAILURE;
  9004. if (res != 0) {
  9005. ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  9006. goto exit;
  9007. }
  9008. }
  9009. attr = xmlSchemaGetPropNode(node, "elementFormDefault");
  9010. if (attr != NULL) {
  9011. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9012. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9013. XML_SCHEMAS_QUALIF_ELEM);
  9014. HFAILURE;
  9015. if (res != 0) {
  9016. xmlSchemaPSimpleTypeErr(ctxt,
  9017. XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
  9018. NULL, (xmlNodePtr) attr, NULL,
  9019. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9020. }
  9021. }
  9022. attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
  9023. if (attr != NULL) {
  9024. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9025. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9026. XML_SCHEMAS_QUALIF_ATTR);
  9027. HFAILURE;
  9028. if (res != 0) {
  9029. xmlSchemaPSimpleTypeErr(ctxt,
  9030. XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
  9031. NULL, (xmlNodePtr) attr, NULL,
  9032. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9033. }
  9034. }
  9035. attr = xmlSchemaGetPropNode(node, "finalDefault");
  9036. if (attr != NULL) {
  9037. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9038. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9039. XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
  9040. XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
  9041. -1,
  9042. XML_SCHEMAS_FINAL_DEFAULT_LIST,
  9043. XML_SCHEMAS_FINAL_DEFAULT_UNION);
  9044. HFAILURE;
  9045. if (res != 0) {
  9046. xmlSchemaPSimpleTypeErr(ctxt,
  9047. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9048. NULL, (xmlNodePtr) attr, NULL,
  9049. "(#all | List of (extension | restriction | list | union))",
  9050. val, NULL, NULL, NULL);
  9051. }
  9052. }
  9053. attr = xmlSchemaGetPropNode(node, "blockDefault");
  9054. if (attr != NULL) {
  9055. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9056. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9057. XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
  9058. XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
  9059. XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
  9060. HFAILURE;
  9061. if (res != 0) {
  9062. xmlSchemaPSimpleTypeErr(ctxt,
  9063. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9064. NULL, (xmlNodePtr) attr, NULL,
  9065. "(#all | List of (extension | restriction | substitution))",
  9066. val, NULL, NULL, NULL);
  9067. }
  9068. }
  9069. exit:
  9070. if (oldErrs != ctxt->nberrors)
  9071. res = ctxt->err;
  9072. return(res);
  9073. exit_failure:
  9074. return(-1);
  9075. }
  9076. /**
  9077. * xmlSchemaParseSchemaTopLevel:
  9078. * @ctxt: a schema validation context
  9079. * @schema: the schemas
  9080. * @nodes: the list of top level nodes
  9081. *
  9082. * Returns the internal XML Schema structure built from the resource or
  9083. * NULL in case of error
  9084. */
  9085. static int
  9086. xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
  9087. xmlSchemaPtr schema, xmlNodePtr nodes)
  9088. {
  9089. xmlNodePtr child;
  9090. xmlSchemaAnnotPtr annot;
  9091. int res = 0, oldErrs, tmpOldErrs;
  9092. if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
  9093. return(-1);
  9094. oldErrs = ctxt->nberrors;
  9095. child = nodes;
  9096. while ((IS_SCHEMA(child, "include")) ||
  9097. (IS_SCHEMA(child, "import")) ||
  9098. (IS_SCHEMA(child, "redefine")) ||
  9099. (IS_SCHEMA(child, "annotation"))) {
  9100. if (IS_SCHEMA(child, "annotation")) {
  9101. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9102. if (schema->annot == NULL)
  9103. schema->annot = annot;
  9104. else
  9105. xmlSchemaFreeAnnot(annot);
  9106. } else if (IS_SCHEMA(child, "import")) {
  9107. tmpOldErrs = ctxt->nberrors;
  9108. res = xmlSchemaParseImport(ctxt, schema, child);
  9109. HFAILURE;
  9110. HSTOP(ctxt);
  9111. if (tmpOldErrs != ctxt->nberrors)
  9112. goto exit;
  9113. } else if (IS_SCHEMA(child, "include")) {
  9114. tmpOldErrs = ctxt->nberrors;
  9115. res = xmlSchemaParseInclude(ctxt, schema, child);
  9116. HFAILURE;
  9117. HSTOP(ctxt);
  9118. if (tmpOldErrs != ctxt->nberrors)
  9119. goto exit;
  9120. } else if (IS_SCHEMA(child, "redefine")) {
  9121. tmpOldErrs = ctxt->nberrors;
  9122. res = xmlSchemaParseRedefine(ctxt, schema, child);
  9123. HFAILURE;
  9124. HSTOP(ctxt);
  9125. if (tmpOldErrs != ctxt->nberrors)
  9126. goto exit;
  9127. }
  9128. child = child->next;
  9129. }
  9130. /*
  9131. * URGENT TODO: Change the functions to return int results.
  9132. * We need especially to catch internal errors.
  9133. */
  9134. while (child != NULL) {
  9135. if (IS_SCHEMA(child, "complexType")) {
  9136. xmlSchemaParseComplexType(ctxt, schema, child, 1);
  9137. child = child->next;
  9138. } else if (IS_SCHEMA(child, "simpleType")) {
  9139. xmlSchemaParseSimpleType(ctxt, schema, child, 1);
  9140. child = child->next;
  9141. } else if (IS_SCHEMA(child, "element")) {
  9142. xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
  9143. child = child->next;
  9144. } else if (IS_SCHEMA(child, "attribute")) {
  9145. xmlSchemaParseGlobalAttribute(ctxt, schema, child);
  9146. child = child->next;
  9147. } else if (IS_SCHEMA(child, "attributeGroup")) {
  9148. xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
  9149. child = child->next;
  9150. } else if (IS_SCHEMA(child, "group")) {
  9151. xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
  9152. child = child->next;
  9153. } else if (IS_SCHEMA(child, "notation")) {
  9154. xmlSchemaParseNotation(ctxt, schema, child);
  9155. child = child->next;
  9156. } else {
  9157. xmlSchemaPContentErr(ctxt,
  9158. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  9159. NULL, child->parent, child,
  9160. NULL, "((include | import | redefine | annotation)*, "
  9161. "(((simpleType | complexType | group | attributeGroup) "
  9162. "| element | attribute | notation), annotation*)*)");
  9163. child = child->next;
  9164. }
  9165. while (IS_SCHEMA(child, "annotation")) {
  9166. /*
  9167. * TODO: We should add all annotations.
  9168. */
  9169. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9170. if (schema->annot == NULL)
  9171. schema->annot = annot;
  9172. else
  9173. xmlSchemaFreeAnnot(annot);
  9174. child = child->next;
  9175. }
  9176. }
  9177. exit:
  9178. ctxt->ctxtType = NULL;
  9179. if (oldErrs != ctxt->nberrors)
  9180. res = ctxt->err;
  9181. return(res);
  9182. exit_failure:
  9183. return(-1);
  9184. }
  9185. static xmlSchemaSchemaRelationPtr
  9186. xmlSchemaSchemaRelationCreate(void)
  9187. {
  9188. xmlSchemaSchemaRelationPtr ret;
  9189. ret = (xmlSchemaSchemaRelationPtr)
  9190. xmlMalloc(sizeof(xmlSchemaSchemaRelation));
  9191. if (ret == NULL) {
  9192. xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
  9193. return(NULL);
  9194. }
  9195. memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
  9196. return(ret);
  9197. }
  9198. #if 0
  9199. static void
  9200. xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
  9201. {
  9202. xmlFree(rel);
  9203. }
  9204. #endif
  9205. static void
  9206. xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
  9207. {
  9208. xmlSchemaRedefPtr prev;
  9209. while (redef != NULL) {
  9210. prev = redef;
  9211. redef = redef->next;
  9212. xmlFree(prev);
  9213. }
  9214. }
  9215. static void
  9216. xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
  9217. {
  9218. /*
  9219. * After the construction context has been freed, there will be
  9220. * no schema graph available any more. Only the schema buckets
  9221. * will stay alive, which are put into the "schemasImports" and
  9222. * "includes" slots of the xmlSchema.
  9223. */
  9224. if (con->buckets != NULL)
  9225. xmlSchemaItemListFree(con->buckets);
  9226. if (con->pending != NULL)
  9227. xmlSchemaItemListFree(con->pending);
  9228. if (con->substGroups != NULL)
  9229. xmlHashFree(con->substGroups,
  9230. (xmlHashDeallocator) xmlSchemaSubstGroupFree);
  9231. if (con->redefs != NULL)
  9232. xmlSchemaRedefListFree(con->redefs);
  9233. if (con->dict != NULL)
  9234. xmlDictFree(con->dict);
  9235. xmlFree(con);
  9236. }
  9237. static xmlSchemaConstructionCtxtPtr
  9238. xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
  9239. {
  9240. xmlSchemaConstructionCtxtPtr ret;
  9241. ret = (xmlSchemaConstructionCtxtPtr)
  9242. xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
  9243. if (ret == NULL) {
  9244. xmlSchemaPErrMemory(NULL,
  9245. "allocating schema construction context", NULL);
  9246. return (NULL);
  9247. }
  9248. memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
  9249. ret->buckets = xmlSchemaItemListCreate();
  9250. if (ret->buckets == NULL) {
  9251. xmlSchemaPErrMemory(NULL,
  9252. "allocating list of schema buckets", NULL);
  9253. xmlFree(ret);
  9254. return (NULL);
  9255. }
  9256. ret->pending = xmlSchemaItemListCreate();
  9257. if (ret->pending == NULL) {
  9258. xmlSchemaPErrMemory(NULL,
  9259. "allocating list of pending global components", NULL);
  9260. xmlSchemaConstructionCtxtFree(ret);
  9261. return (NULL);
  9262. }
  9263. ret->dict = dict;
  9264. xmlDictReference(dict);
  9265. return(ret);
  9266. }
  9267. static xmlSchemaParserCtxtPtr
  9268. xmlSchemaParserCtxtCreate(void)
  9269. {
  9270. xmlSchemaParserCtxtPtr ret;
  9271. ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
  9272. if (ret == NULL) {
  9273. xmlSchemaPErrMemory(NULL, "allocating schema parser context",
  9274. NULL);
  9275. return (NULL);
  9276. }
  9277. memset(ret, 0, sizeof(xmlSchemaParserCtxt));
  9278. ret->type = XML_SCHEMA_CTXT_PARSER;
  9279. ret->attrProhibs = xmlSchemaItemListCreate();
  9280. if (ret->attrProhibs == NULL) {
  9281. xmlFree(ret);
  9282. return(NULL);
  9283. }
  9284. return(ret);
  9285. }
  9286. /**
  9287. * xmlSchemaNewParserCtxtUseDict:
  9288. * @URL: the location of the schema
  9289. * @dict: the dictionary to be used
  9290. *
  9291. * Create an XML Schemas parse context for that file/resource expected
  9292. * to contain an XML Schemas file.
  9293. *
  9294. * Returns the parser context or NULL in case of error
  9295. */
  9296. static xmlSchemaParserCtxtPtr
  9297. xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
  9298. {
  9299. xmlSchemaParserCtxtPtr ret;
  9300. ret = xmlSchemaParserCtxtCreate();
  9301. if (ret == NULL)
  9302. return (NULL);
  9303. ret->dict = dict;
  9304. xmlDictReference(dict);
  9305. if (URL != NULL)
  9306. ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
  9307. return (ret);
  9308. }
  9309. static int
  9310. xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
  9311. {
  9312. if (vctxt->pctxt == NULL) {
  9313. if (vctxt->schema != NULL)
  9314. vctxt->pctxt =
  9315. xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
  9316. else
  9317. vctxt->pctxt = xmlSchemaNewParserCtxt("*");
  9318. if (vctxt->pctxt == NULL) {
  9319. VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
  9320. "failed to create a temp. parser context");
  9321. return (-1);
  9322. }
  9323. /* TODO: Pass user data. */
  9324. xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
  9325. vctxt->warning, vctxt->errCtxt);
  9326. xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
  9327. vctxt->errCtxt);
  9328. }
  9329. return (0);
  9330. }
  9331. /**
  9332. * xmlSchemaGetSchemaBucket:
  9333. * @pctxt: the schema parser context
  9334. * @schemaLocation: the URI of the schema document
  9335. *
  9336. * Returns a schema bucket if it was already parsed.
  9337. *
  9338. * Returns a schema bucket if it was already parsed from
  9339. * @schemaLocation, NULL otherwise.
  9340. */
  9341. static xmlSchemaBucketPtr
  9342. xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9343. const xmlChar *schemaLocation)
  9344. {
  9345. xmlSchemaBucketPtr cur;
  9346. xmlSchemaItemListPtr list;
  9347. list = pctxt->constructor->buckets;
  9348. if (list->nbItems == 0)
  9349. return(NULL);
  9350. else {
  9351. int i;
  9352. for (i = 0; i < list->nbItems; i++) {
  9353. cur = (xmlSchemaBucketPtr) list->items[i];
  9354. /* Pointer comparison! */
  9355. if (cur->schemaLocation == schemaLocation)
  9356. return(cur);
  9357. }
  9358. }
  9359. return(NULL);
  9360. }
  9361. static xmlSchemaBucketPtr
  9362. xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9363. const xmlChar *schemaLocation,
  9364. const xmlChar *targetNamespace)
  9365. {
  9366. xmlSchemaBucketPtr cur;
  9367. xmlSchemaItemListPtr list;
  9368. list = pctxt->constructor->buckets;
  9369. if (list->nbItems == 0)
  9370. return(NULL);
  9371. else {
  9372. int i;
  9373. for (i = 0; i < list->nbItems; i++) {
  9374. cur = (xmlSchemaBucketPtr) list->items[i];
  9375. /* Pointer comparison! */
  9376. if ((cur->origTargetNamespace == NULL) &&
  9377. (cur->schemaLocation == schemaLocation) &&
  9378. (cur->targetNamespace == targetNamespace))
  9379. return(cur);
  9380. }
  9381. }
  9382. return(NULL);
  9383. }
  9384. #define IS_BAD_SCHEMA_DOC(b) \
  9385. (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
  9386. static xmlSchemaBucketPtr
  9387. xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
  9388. const xmlChar *targetNamespace,
  9389. int imported)
  9390. {
  9391. xmlSchemaBucketPtr cur;
  9392. xmlSchemaItemListPtr list;
  9393. list = pctxt->constructor->buckets;
  9394. if (list->nbItems == 0)
  9395. return(NULL);
  9396. else {
  9397. int i;
  9398. for (i = 0; i < list->nbItems; i++) {
  9399. cur = (xmlSchemaBucketPtr) list->items[i];
  9400. if ((! IS_BAD_SCHEMA_DOC(cur)) &&
  9401. (cur->origTargetNamespace == targetNamespace) &&
  9402. ((imported && cur->imported) ||
  9403. ((!imported) && (!cur->imported))))
  9404. return(cur);
  9405. }
  9406. }
  9407. return(NULL);
  9408. }
  9409. static int
  9410. xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
  9411. xmlSchemaPtr schema,
  9412. xmlSchemaBucketPtr bucket)
  9413. {
  9414. int oldFlags;
  9415. xmlDocPtr oldDoc;
  9416. xmlNodePtr node;
  9417. int ret, oldErrs;
  9418. xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
  9419. /*
  9420. * Save old values; reset the *main* schema.
  9421. * URGENT TODO: This is not good; move the per-document information
  9422. * to the parser. Get rid of passing the main schema to the
  9423. * parsing functions.
  9424. */
  9425. oldFlags = schema->flags;
  9426. oldDoc = schema->doc;
  9427. if (schema->flags != 0)
  9428. xmlSchemaClearSchemaDefaults(schema);
  9429. schema->doc = bucket->doc;
  9430. pctxt->schema = schema;
  9431. /*
  9432. * Keep the current target namespace on the parser *not* on the
  9433. * main schema.
  9434. */
  9435. pctxt->targetNamespace = bucket->targetNamespace;
  9436. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  9437. if ((bucket->targetNamespace != NULL) &&
  9438. xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
  9439. /*
  9440. * We are parsing the schema for schemas!
  9441. */
  9442. pctxt->isS4S = 1;
  9443. }
  9444. /* Mark it as parsed, even if parsing fails. */
  9445. bucket->parsed++;
  9446. /* Compile the schema doc. */
  9447. node = xmlDocGetRootElement(bucket->doc);
  9448. ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
  9449. if (ret != 0)
  9450. goto exit;
  9451. /* An empty schema; just get out. */
  9452. if (node->children == NULL)
  9453. goto exit;
  9454. oldErrs = pctxt->nberrors;
  9455. ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
  9456. if (ret != 0)
  9457. goto exit;
  9458. /*
  9459. * TODO: Not nice, but I'm not 100% sure we will get always an error
  9460. * as a result of the obove functions; so better rely on pctxt->err
  9461. * as well.
  9462. */
  9463. if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
  9464. ret = pctxt->err;
  9465. goto exit;
  9466. }
  9467. exit:
  9468. WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
  9469. /* Restore schema values. */
  9470. schema->doc = oldDoc;
  9471. schema->flags = oldFlags;
  9472. return(ret);
  9473. }
  9474. static int
  9475. xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
  9476. xmlSchemaPtr schema,
  9477. xmlSchemaBucketPtr bucket)
  9478. {
  9479. xmlSchemaParserCtxtPtr newpctxt;
  9480. int res = 0;
  9481. if (bucket == NULL)
  9482. return(0);
  9483. if (bucket->parsed) {
  9484. PERROR_INT("xmlSchemaParseNewDoc",
  9485. "reparsing a schema doc");
  9486. return(-1);
  9487. }
  9488. if (bucket->doc == NULL) {
  9489. PERROR_INT("xmlSchemaParseNewDoc",
  9490. "parsing a schema doc, but there's no doc");
  9491. return(-1);
  9492. }
  9493. if (pctxt->constructor == NULL) {
  9494. PERROR_INT("xmlSchemaParseNewDoc",
  9495. "no constructor");
  9496. return(-1);
  9497. }
  9498. /* Create and init the temporary parser context. */
  9499. newpctxt = xmlSchemaNewParserCtxtUseDict(
  9500. (const char *) bucket->schemaLocation, pctxt->dict);
  9501. if (newpctxt == NULL)
  9502. return(-1);
  9503. newpctxt->constructor = pctxt->constructor;
  9504. /*
  9505. * TODO: Can we avoid that the parser knows about the main schema?
  9506. * It would be better if he knows about the current schema bucket
  9507. * only.
  9508. */
  9509. newpctxt->schema = schema;
  9510. xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
  9511. pctxt->errCtxt);
  9512. xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
  9513. pctxt->errCtxt);
  9514. newpctxt->counter = pctxt->counter;
  9515. res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
  9516. /* Channel back errors and cleanup the temporary parser context. */
  9517. if (res != 0)
  9518. pctxt->err = res;
  9519. pctxt->nberrors += newpctxt->nberrors;
  9520. pctxt->counter = newpctxt->counter;
  9521. newpctxt->constructor = NULL;
  9522. /* Free the parser context. */
  9523. xmlSchemaFreeParserCtxt(newpctxt);
  9524. return(res);
  9525. }
  9526. static void
  9527. xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
  9528. xmlSchemaSchemaRelationPtr rel)
  9529. {
  9530. xmlSchemaSchemaRelationPtr cur = bucket->relations;
  9531. if (cur == NULL) {
  9532. bucket->relations = rel;
  9533. return;
  9534. }
  9535. while (cur->next != NULL)
  9536. cur = cur->next;
  9537. cur->next = rel;
  9538. }
  9539. static const xmlChar *
  9540. xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
  9541. xmlNodePtr ctxtNode)
  9542. {
  9543. /*
  9544. * Build an absolue location URI.
  9545. */
  9546. if (location != NULL) {
  9547. if (ctxtNode == NULL)
  9548. return(location);
  9549. else {
  9550. xmlChar *base, *URI;
  9551. const xmlChar *ret = NULL;
  9552. base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
  9553. if (base == NULL) {
  9554. URI = xmlBuildURI(location, ctxtNode->doc->URL);
  9555. } else {
  9556. URI = xmlBuildURI(location, base);
  9557. xmlFree(base);
  9558. }
  9559. if (URI != NULL) {
  9560. ret = xmlDictLookup(dict, URI, -1);
  9561. xmlFree(URI);
  9562. return(ret);
  9563. }
  9564. }
  9565. }
  9566. return(NULL);
  9567. }
  9568. /**
  9569. * xmlSchemaAddSchemaDoc:
  9570. * @pctxt: a schema validation context
  9571. * @schema: the schema being built
  9572. * @node: a subtree containing XML Schema informations
  9573. *
  9574. * Parse an included (and to-be-redefined) XML schema document.
  9575. *
  9576. * Returns 0 on success, a positive error code on errors and
  9577. * -1 in case of an internal or API error.
  9578. */
  9579. static int
  9580. xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
  9581. int type, /* import or include or redefine */
  9582. const xmlChar *schemaLocation,
  9583. xmlDocPtr schemaDoc,
  9584. const char *schemaBuffer,
  9585. int schemaBufferLen,
  9586. xmlNodePtr invokingNode,
  9587. const xmlChar *sourceTargetNamespace,
  9588. const xmlChar *importNamespace,
  9589. xmlSchemaBucketPtr *bucket)
  9590. {
  9591. const xmlChar *targetNamespace = NULL;
  9592. xmlSchemaSchemaRelationPtr relation = NULL;
  9593. xmlDocPtr doc = NULL;
  9594. int res = 0, err = 0, located = 0, preserveDoc = 0;
  9595. xmlSchemaBucketPtr bkt = NULL;
  9596. if (bucket != NULL)
  9597. *bucket = NULL;
  9598. switch (type) {
  9599. case XML_SCHEMA_SCHEMA_IMPORT:
  9600. case XML_SCHEMA_SCHEMA_MAIN:
  9601. err = XML_SCHEMAP_SRC_IMPORT;
  9602. break;
  9603. case XML_SCHEMA_SCHEMA_INCLUDE:
  9604. err = XML_SCHEMAP_SRC_INCLUDE;
  9605. break;
  9606. case XML_SCHEMA_SCHEMA_REDEFINE:
  9607. err = XML_SCHEMAP_SRC_REDEFINE;
  9608. break;
  9609. }
  9610. /* Special handling for the main schema:
  9611. * skip the location and relation logic and just parse the doc.
  9612. * We need just a bucket to be returned in this case.
  9613. */
  9614. if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
  9615. goto doc_load;
  9616. /* Note that we expect the location to be an absulute URI. */
  9617. if (schemaLocation != NULL) {
  9618. bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
  9619. if ((bkt != NULL) &&
  9620. (pctxt->constructor->bucket == bkt)) {
  9621. /* Report self-imports/inclusions/redefinitions. */
  9622. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9623. invokingNode, NULL,
  9624. "The schema must not import/include/redefine itself",
  9625. NULL, NULL);
  9626. goto exit;
  9627. }
  9628. }
  9629. /*
  9630. * Create a relation for the graph of schemas.
  9631. */
  9632. relation = xmlSchemaSchemaRelationCreate();
  9633. if (relation == NULL)
  9634. return(-1);
  9635. xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
  9636. relation);
  9637. relation->type = type;
  9638. /*
  9639. * Save the namespace import information.
  9640. */
  9641. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9642. relation->importNamespace = importNamespace;
  9643. if (schemaLocation == NULL) {
  9644. /*
  9645. * No location; this is just an import of the namespace.
  9646. * Note that we don't assign a bucket to the relation
  9647. * in this case.
  9648. */
  9649. goto exit;
  9650. }
  9651. targetNamespace = importNamespace;
  9652. }
  9653. /* Did we already fetch the doc? */
  9654. if (bkt != NULL) {
  9655. if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
  9656. /*
  9657. * We included/redefined and then try to import a schema,
  9658. * but the new location provided for import was different.
  9659. */
  9660. if (schemaLocation == NULL)
  9661. schemaLocation = BAD_CAST "in_memory_buffer";
  9662. if (!xmlStrEqual(schemaLocation,
  9663. bkt->schemaLocation)) {
  9664. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9665. invokingNode, NULL,
  9666. "The schema document '%s' cannot be imported, since "
  9667. "it was already included or redefined",
  9668. schemaLocation, NULL);
  9669. goto exit;
  9670. }
  9671. } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
  9672. /*
  9673. * We imported and then try to include/redefine a schema,
  9674. * but the new location provided for the include/redefine
  9675. * was different.
  9676. */
  9677. if (schemaLocation == NULL)
  9678. schemaLocation = BAD_CAST "in_memory_buffer";
  9679. if (!xmlStrEqual(schemaLocation,
  9680. bkt->schemaLocation)) {
  9681. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9682. invokingNode, NULL,
  9683. "The schema document '%s' cannot be included or "
  9684. "redefined, since it was already imported",
  9685. schemaLocation, NULL);
  9686. goto exit;
  9687. }
  9688. }
  9689. }
  9690. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9691. /*
  9692. * Given that the schemaLocation [attribute] is only a hint, it is open
  9693. * to applications to ignore all but the first <import> for a given
  9694. * namespace, regardless of the �actual value� of schemaLocation, but
  9695. * such a strategy risks missing useful information when new
  9696. * schemaLocations are offered.
  9697. *
  9698. * We will use the first <import> that comes with a location.
  9699. * Further <import>s *with* a location, will result in an error.
  9700. * TODO: Better would be to just report a warning here, but
  9701. * we'll try it this way until someone complains.
  9702. *
  9703. * Schema Document Location Strategy:
  9704. * 3 Based on the namespace name, identify an existing schema document,
  9705. * either as a resource which is an XML document or a <schema> element
  9706. * information item, in some local schema repository;
  9707. * 5 Attempt to resolve the namespace name to locate such a resource.
  9708. *
  9709. * NOTE: (3) and (5) are not supported.
  9710. */
  9711. if (bkt != NULL) {
  9712. relation->bucket = bkt;
  9713. goto exit;
  9714. }
  9715. bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
  9716. importNamespace, 1);
  9717. if (bkt != NULL) {
  9718. relation->bucket = bkt;
  9719. if (bkt->schemaLocation == NULL) {
  9720. /* First given location of the schema; load the doc. */
  9721. bkt->schemaLocation = schemaLocation;
  9722. } else {
  9723. if (!xmlStrEqual(schemaLocation,
  9724. bkt->schemaLocation)) {
  9725. /*
  9726. * Additional location given; just skip it.
  9727. * URGENT TODO: We should report a warning here.
  9728. * res = XML_SCHEMAP_SRC_IMPORT;
  9729. */
  9730. if (schemaLocation == NULL)
  9731. schemaLocation = BAD_CAST "in_memory_buffer";
  9732. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  9733. XML_SCHEMAP_WARN_SKIP_SCHEMA,
  9734. invokingNode, NULL,
  9735. "Skipping import of schema located at '%s' for the "
  9736. "namespace '%s', since this namespace was already "
  9737. "imported with the schema located at '%s'",
  9738. schemaLocation, importNamespace, bkt->schemaLocation);
  9739. }
  9740. goto exit;
  9741. }
  9742. }
  9743. /*
  9744. * No bucket + first location: load the doc and create a
  9745. * bucket.
  9746. */
  9747. } else {
  9748. /* <include> and <redefine> */
  9749. if (bkt != NULL) {
  9750. if ((bkt->origTargetNamespace == NULL) &&
  9751. (bkt->targetNamespace != sourceTargetNamespace)) {
  9752. xmlSchemaBucketPtr chamel;
  9753. /*
  9754. * Chameleon include/redefine: skip loading only if it was
  9755. * aleady build for the targetNamespace of the including
  9756. * schema.
  9757. */
  9758. /*
  9759. * URGENT TODO: If the schema is a chameleon-include then copy
  9760. * the components into the including schema and modify the
  9761. * targetNamespace of those components, do nothing otherwise.
  9762. * NOTE: This is currently worked-around by compiling the
  9763. * chameleon for every destinct including targetNamespace; thus
  9764. * not performant at the moment.
  9765. * TODO: Check when the namespace in wildcards for chameleons
  9766. * needs to be converted: before we built wildcard intersections
  9767. * or after.
  9768. * Answer: after!
  9769. */
  9770. chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
  9771. schemaLocation, sourceTargetNamespace);
  9772. if (chamel != NULL) {
  9773. /* A fitting chameleon was already parsed; NOP. */
  9774. relation->bucket = chamel;
  9775. goto exit;
  9776. }
  9777. /*
  9778. * We need to parse the chameleon again for a different
  9779. * targetNamespace.
  9780. * CHAMELEON TODO: Optimize this by only parsing the
  9781. * chameleon once, and then copying the components to
  9782. * the new targetNamespace.
  9783. */
  9784. bkt = NULL;
  9785. } else {
  9786. relation->bucket = bkt;
  9787. goto exit;
  9788. }
  9789. }
  9790. }
  9791. if ((bkt != NULL) && (bkt->doc != NULL)) {
  9792. PERROR_INT("xmlSchemaAddSchemaDoc",
  9793. "trying to load a schema doc, but a doc is already "
  9794. "assigned to the schema bucket");
  9795. goto exit_failure;
  9796. }
  9797. doc_load:
  9798. /*
  9799. * Load the document.
  9800. */
  9801. if (schemaDoc != NULL) {
  9802. doc = schemaDoc;
  9803. /* Don' free this one, since it was provided by the caller. */
  9804. preserveDoc = 1;
  9805. /* TODO: Does the context or the doc hold the location? */
  9806. if (schemaDoc->URL != NULL)
  9807. schemaLocation = xmlDictLookup(pctxt->dict,
  9808. schemaDoc->URL, -1);
  9809. else
  9810. schemaLocation = BAD_CAST "in_memory_buffer";
  9811. } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
  9812. xmlParserCtxtPtr parserCtxt;
  9813. parserCtxt = xmlNewParserCtxt();
  9814. if (parserCtxt == NULL) {
  9815. xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
  9816. "allocating a parser context", NULL);
  9817. goto exit_failure;
  9818. }
  9819. if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
  9820. /*
  9821. * TODO: Do we have to burden the schema parser dict with all
  9822. * the content of the schema doc?
  9823. */
  9824. xmlDictFree(parserCtxt->dict);
  9825. parserCtxt->dict = pctxt->dict;
  9826. xmlDictReference(parserCtxt->dict);
  9827. }
  9828. if (schemaLocation != NULL) {
  9829. /* Parse from file. */
  9830. doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
  9831. NULL, SCHEMAS_PARSE_OPTIONS);
  9832. } else if (schemaBuffer != NULL) {
  9833. /* Parse from memory buffer. */
  9834. doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
  9835. NULL, NULL, SCHEMAS_PARSE_OPTIONS);
  9836. schemaLocation = BAD_CAST "in_memory_buffer";
  9837. if (doc != NULL)
  9838. doc->URL = xmlStrdup(schemaLocation);
  9839. }
  9840. /*
  9841. * For <import>:
  9842. * 2.1 The referent is (a fragment of) a resource which is an
  9843. * XML document (see clause 1.1), which in turn corresponds to
  9844. * a <schema> element information item in a well-formed information
  9845. * set, which in turn corresponds to a valid schema.
  9846. * TODO: (2.1) fragments of XML documents are not supported.
  9847. *
  9848. * 2.2 The referent is a <schema> element information item in
  9849. * a well-formed information set, which in turn corresponds
  9850. * to a valid schema.
  9851. * TODO: (2.2) is not supported.
  9852. */
  9853. if (doc == NULL) {
  9854. xmlErrorPtr lerr;
  9855. lerr = xmlGetLastError();
  9856. /*
  9857. * Check if this a parser error, or if the document could
  9858. * just not be located.
  9859. * TODO: Try to find specific error codes to react only on
  9860. * localisation failures.
  9861. */
  9862. if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
  9863. /*
  9864. * We assume a parser error here.
  9865. */
  9866. located = 1;
  9867. /* TODO: Error code ?? */
  9868. res = XML_SCHEMAP_SRC_IMPORT_2_1;
  9869. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  9870. invokingNode, NULL,
  9871. "Failed to parse the XML resource '%s'",
  9872. schemaLocation, NULL);
  9873. }
  9874. }
  9875. xmlFreeParserCtxt(parserCtxt);
  9876. if ((doc == NULL) && located)
  9877. goto exit_error;
  9878. } else {
  9879. xmlSchemaPErr(pctxt, NULL,
  9880. XML_SCHEMAP_NOTHING_TO_PARSE,
  9881. "No information for parsing was provided with the "
  9882. "given schema parser context.\n",
  9883. NULL, NULL);
  9884. goto exit_failure;
  9885. }
  9886. /*
  9887. * Preprocess the document.
  9888. */
  9889. if (doc != NULL) {
  9890. xmlNodePtr docElem = NULL;
  9891. located = 1;
  9892. docElem = xmlDocGetRootElement(doc);
  9893. if (docElem == NULL) {
  9894. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
  9895. invokingNode, NULL,
  9896. "The document '%s' has no document element",
  9897. schemaLocation, NULL);
  9898. goto exit_error;
  9899. }
  9900. /*
  9901. * Remove all the blank text nodes.
  9902. */
  9903. xmlSchemaCleanupDoc(pctxt, docElem);
  9904. /*
  9905. * Check the schema's top level element.
  9906. */
  9907. if (!IS_SCHEMA(docElem, "schema")) {
  9908. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
  9909. invokingNode, NULL,
  9910. "The XML document '%s' is not a schema document",
  9911. schemaLocation, NULL);
  9912. goto exit_error;
  9913. }
  9914. /*
  9915. * Note that we don't apply a type check for the
  9916. * targetNamespace value here.
  9917. */
  9918. targetNamespace = xmlSchemaGetProp(pctxt, docElem,
  9919. "targetNamespace");
  9920. }
  9921. /* after_doc_loading: */
  9922. if ((bkt == NULL) && located) {
  9923. /* Only create a bucket if the schema was located. */
  9924. bkt = xmlSchemaBucketCreate(pctxt, type,
  9925. targetNamespace);
  9926. if (bkt == NULL)
  9927. goto exit_failure;
  9928. }
  9929. if (bkt != NULL) {
  9930. bkt->schemaLocation = schemaLocation;
  9931. bkt->located = located;
  9932. if (doc != NULL) {
  9933. bkt->doc = doc;
  9934. bkt->targetNamespace = targetNamespace;
  9935. bkt->origTargetNamespace = targetNamespace;
  9936. if (preserveDoc)
  9937. bkt->preserveDoc = 1;
  9938. }
  9939. if (WXS_IS_BUCKET_IMPMAIN(type))
  9940. bkt->imported++;
  9941. /*
  9942. * Add it to the graph of schemas.
  9943. */
  9944. if (relation != NULL)
  9945. relation->bucket = bkt;
  9946. }
  9947. exit:
  9948. /*
  9949. * Return the bucket explicitely; this is needed for the
  9950. * main schema.
  9951. */
  9952. if (bucket != NULL)
  9953. *bucket = bkt;
  9954. return (0);
  9955. exit_error:
  9956. if ((doc != NULL) && (! preserveDoc)) {
  9957. xmlFreeDoc(doc);
  9958. if (bkt != NULL)
  9959. bkt->doc = NULL;
  9960. }
  9961. return(pctxt->err);
  9962. exit_failure:
  9963. if ((doc != NULL) && (! preserveDoc)) {
  9964. xmlFreeDoc(doc);
  9965. if (bkt != NULL)
  9966. bkt->doc = NULL;
  9967. }
  9968. return (-1);
  9969. }
  9970. /**
  9971. * xmlSchemaParseImport:
  9972. * @ctxt: a schema validation context
  9973. * @schema: the schema being built
  9974. * @node: a subtree containing XML Schema informations
  9975. *
  9976. * parse a XML schema Import definition
  9977. * *WARNING* this interface is highly subject to change
  9978. *
  9979. * Returns 0 in case of success, a positive error code if
  9980. * not valid and -1 in case of an internal error.
  9981. */
  9982. static int
  9983. xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  9984. xmlNodePtr node)
  9985. {
  9986. xmlNodePtr child;
  9987. const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
  9988. const xmlChar *thisTargetNamespace;
  9989. xmlAttrPtr attr;
  9990. int ret = 0;
  9991. xmlSchemaBucketPtr bucket = NULL;
  9992. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  9993. return (-1);
  9994. /*
  9995. * Check for illegal attributes.
  9996. */
  9997. attr = node->properties;
  9998. while (attr != NULL) {
  9999. if (attr->ns == NULL) {
  10000. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10001. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  10002. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10003. xmlSchemaPIllegalAttrErr(pctxt,
  10004. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10005. }
  10006. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10007. xmlSchemaPIllegalAttrErr(pctxt,
  10008. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10009. }
  10010. attr = attr->next;
  10011. }
  10012. /*
  10013. * Extract and validate attributes.
  10014. */
  10015. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10016. "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10017. &namespaceName) != 0) {
  10018. xmlSchemaPSimpleTypeErr(pctxt,
  10019. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10020. NULL, node,
  10021. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10022. NULL, namespaceName, NULL, NULL, NULL);
  10023. return (pctxt->err);
  10024. }
  10025. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10026. "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10027. &schemaLocation) != 0) {
  10028. xmlSchemaPSimpleTypeErr(pctxt,
  10029. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10030. NULL, node,
  10031. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10032. NULL, namespaceName, NULL, NULL, NULL);
  10033. return (pctxt->err);
  10034. }
  10035. /*
  10036. * And now for the children...
  10037. */
  10038. child = node->children;
  10039. if (IS_SCHEMA(child, "annotation")) {
  10040. /*
  10041. * the annotation here is simply discarded ...
  10042. * TODO: really?
  10043. */
  10044. child = child->next;
  10045. }
  10046. if (child != NULL) {
  10047. xmlSchemaPContentErr(pctxt,
  10048. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10049. NULL, node, child, NULL,
  10050. "(annotation?)");
  10051. }
  10052. /*
  10053. * Apply additional constraints.
  10054. *
  10055. * Note that it is important to use the original @targetNamespace
  10056. * (or none at all), to rule out imports of schemas _with_ a
  10057. * @targetNamespace if the importing schema is a chameleon schema
  10058. * (with no @targetNamespace).
  10059. */
  10060. thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
  10061. if (namespaceName != NULL) {
  10062. /*
  10063. * 1.1 If the namespace [attribute] is present, then its �actual value�
  10064. * must not match the �actual value� of the enclosing <schema>'s
  10065. * targetNamespace [attribute].
  10066. */
  10067. if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
  10068. xmlSchemaPCustomErr(pctxt,
  10069. XML_SCHEMAP_SRC_IMPORT_1_1,
  10070. NULL, node,
  10071. "The value of the attribute 'namespace' must not match "
  10072. "the target namespace '%s' of the importing schema",
  10073. thisTargetNamespace);
  10074. return (pctxt->err);
  10075. }
  10076. } else {
  10077. /*
  10078. * 1.2 If the namespace [attribute] is not present, then the enclosing
  10079. * <schema> must have a targetNamespace [attribute].
  10080. */
  10081. if (thisTargetNamespace == NULL) {
  10082. xmlSchemaPCustomErr(pctxt,
  10083. XML_SCHEMAP_SRC_IMPORT_1_2,
  10084. NULL, node,
  10085. "The attribute 'namespace' must be existent if "
  10086. "the importing schema has no target namespace",
  10087. NULL);
  10088. return (pctxt->err);
  10089. }
  10090. }
  10091. /*
  10092. * Locate and acquire the schema document.
  10093. */
  10094. if (schemaLocation != NULL)
  10095. schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  10096. schemaLocation, node);
  10097. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  10098. schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
  10099. namespaceName, &bucket);
  10100. if (ret != 0)
  10101. return(ret);
  10102. /*
  10103. * For <import>: "It is *not* an error for the application
  10104. * schema reference strategy to fail."
  10105. * So just don't parse if no schema document was found.
  10106. * Note that we will get no bucket if the schema could not be
  10107. * located or if there was no schemaLocation.
  10108. */
  10109. if ((bucket == NULL) && (schemaLocation != NULL)) {
  10110. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  10111. XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
  10112. node, NULL,
  10113. "Failed to locate a schema at location '%s'. "
  10114. "Skipping the import", schemaLocation, NULL, NULL);
  10115. }
  10116. if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
  10117. ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10118. }
  10119. return (ret);
  10120. }
  10121. static int
  10122. xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
  10123. xmlSchemaPtr schema,
  10124. xmlNodePtr node,
  10125. xmlChar **schemaLocation,
  10126. int type)
  10127. {
  10128. xmlAttrPtr attr;
  10129. if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
  10130. (schemaLocation == NULL))
  10131. return (-1);
  10132. *schemaLocation = NULL;
  10133. /*
  10134. * Check for illegal attributes.
  10135. * Applies for both <include> and <redefine>.
  10136. */
  10137. attr = node->properties;
  10138. while (attr != NULL) {
  10139. if (attr->ns == NULL) {
  10140. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10141. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10142. xmlSchemaPIllegalAttrErr(pctxt,
  10143. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10144. }
  10145. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10146. xmlSchemaPIllegalAttrErr(pctxt,
  10147. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10148. }
  10149. attr = attr->next;
  10150. }
  10151. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  10152. /*
  10153. * Preliminary step, extract the URI-Reference and make an URI
  10154. * from the base.
  10155. */
  10156. /*
  10157. * Attribute "schemaLocation" is mandatory.
  10158. */
  10159. attr = xmlSchemaGetPropNode(node, "schemaLocation");
  10160. if (attr != NULL) {
  10161. xmlChar *base = NULL;
  10162. xmlChar *uri = NULL;
  10163. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  10164. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10165. (const xmlChar **) schemaLocation) != 0)
  10166. goto exit_error;
  10167. base = xmlNodeGetBase(node->doc, node);
  10168. if (base == NULL) {
  10169. uri = xmlBuildURI(*schemaLocation, node->doc->URL);
  10170. } else {
  10171. uri = xmlBuildURI(*schemaLocation, base);
  10172. xmlFree(base);
  10173. }
  10174. if (uri == NULL) {
  10175. PERROR_INT("xmlSchemaParseIncludeOrRedefine",
  10176. "could not build an URI from the schemaLocation")
  10177. goto exit_failure;
  10178. }
  10179. (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
  10180. xmlFree(uri);
  10181. } else {
  10182. xmlSchemaPMissingAttrErr(pctxt,
  10183. XML_SCHEMAP_S4S_ATTR_MISSING,
  10184. NULL, node, "schemaLocation", NULL);
  10185. goto exit_error;
  10186. }
  10187. /*
  10188. * Report self-inclusion and self-redefinition.
  10189. */
  10190. if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
  10191. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10192. xmlSchemaPCustomErr(pctxt,
  10193. XML_SCHEMAP_SRC_REDEFINE,
  10194. NULL, node,
  10195. "The schema document '%s' cannot redefine itself.",
  10196. *schemaLocation);
  10197. } else {
  10198. xmlSchemaPCustomErr(pctxt,
  10199. XML_SCHEMAP_SRC_INCLUDE,
  10200. NULL, node,
  10201. "The schema document '%s' cannot include itself.",
  10202. *schemaLocation);
  10203. }
  10204. goto exit_error;
  10205. }
  10206. return(0);
  10207. exit_error:
  10208. return(pctxt->err);
  10209. exit_failure:
  10210. return(-1);
  10211. }
  10212. static int
  10213. xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
  10214. xmlSchemaPtr schema,
  10215. xmlNodePtr node,
  10216. int type)
  10217. {
  10218. xmlNodePtr child = NULL;
  10219. const xmlChar *schemaLocation = NULL;
  10220. int res = 0; /* hasRedefinitions = 0 */
  10221. int isChameleon = 0, wasChameleon = 0;
  10222. xmlSchemaBucketPtr bucket = NULL;
  10223. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10224. return (-1);
  10225. /*
  10226. * Parse attributes. Note that the returned schemaLocation will
  10227. * be already converted to an absolute URI.
  10228. */
  10229. res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
  10230. node, (xmlChar **) (&schemaLocation), type);
  10231. if (res != 0)
  10232. return(res);
  10233. /*
  10234. * Load and add the schema document.
  10235. */
  10236. res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
  10237. NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
  10238. if (res != 0)
  10239. return(res);
  10240. /*
  10241. * If we get no schema bucket back, then this means that the schema
  10242. * document could not be located or was broken XML or was not
  10243. * a schema document.
  10244. */
  10245. if ((bucket == NULL) || (bucket->doc == NULL)) {
  10246. if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
  10247. /*
  10248. * WARNING for <include>:
  10249. * We will raise an error if the schema cannot be located
  10250. * for inclusions, since the that was the feedback from the
  10251. * schema people. I.e. the following spec piece will *not* be
  10252. * satisfied:
  10253. * SPEC src-include: "It is not an error for the �actual value� of the
  10254. * schemaLocation [attribute] to fail to resolve it all, in which
  10255. * case no corresponding inclusion is performed.
  10256. * So do we need a warning report here?"
  10257. */
  10258. res = XML_SCHEMAP_SRC_INCLUDE;
  10259. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10260. node, NULL,
  10261. "Failed to load the document '%s' for inclusion",
  10262. schemaLocation, NULL);
  10263. } else {
  10264. /*
  10265. * NOTE: This was changed to raise an error even if no redefinitions
  10266. * are specified.
  10267. *
  10268. * SPEC src-redefine (1)
  10269. * "If there are any element information items among the [children]
  10270. * other than <annotation> then the �actual value� of the
  10271. * schemaLocation [attribute] must successfully resolve."
  10272. * TODO: Ask the WG if a the location has always to resolve
  10273. * here as well!
  10274. */
  10275. res = XML_SCHEMAP_SRC_REDEFINE;
  10276. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10277. node, NULL,
  10278. "Failed to load the document '%s' for redefinition",
  10279. schemaLocation, NULL);
  10280. }
  10281. } else {
  10282. /*
  10283. * Check targetNamespace sanity before parsing the new schema.
  10284. * TODO: Note that we won't check further content if the
  10285. * targetNamespace was bad.
  10286. */
  10287. if (bucket->origTargetNamespace != NULL) {
  10288. /*
  10289. * SPEC src-include (2.1)
  10290. * "SII has a targetNamespace [attribute], and its �actual
  10291. * value� is identical to the �actual value� of the targetNamespace
  10292. * [attribute] of SII� (which must have such an [attribute])."
  10293. */
  10294. if (pctxt->targetNamespace == NULL) {
  10295. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10296. XML_SCHEMAP_SRC_INCLUDE,
  10297. node, NULL,
  10298. "The target namespace of the included/redefined schema "
  10299. "'%s' has to be absent, since the including/redefining "
  10300. "schema has no target namespace",
  10301. schemaLocation, NULL);
  10302. goto exit_error;
  10303. } else if (!xmlStrEqual(bucket->origTargetNamespace,
  10304. pctxt->targetNamespace)) {
  10305. /* TODO: Change error function. */
  10306. xmlSchemaPCustomErrExt(pctxt,
  10307. XML_SCHEMAP_SRC_INCLUDE,
  10308. NULL, node,
  10309. "The target namespace '%s' of the included/redefined "
  10310. "schema '%s' differs from '%s' of the "
  10311. "including/redefining schema",
  10312. bucket->origTargetNamespace, schemaLocation,
  10313. pctxt->targetNamespace);
  10314. goto exit_error;
  10315. }
  10316. } else if (pctxt->targetNamespace != NULL) {
  10317. /*
  10318. * Chameleons: the original target namespace will
  10319. * differ from the resulting namespace.
  10320. */
  10321. isChameleon = 1;
  10322. if (bucket->parsed &&
  10323. bucket->origTargetNamespace != NULL) {
  10324. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10325. XML_SCHEMAP_SRC_INCLUDE,
  10326. node, NULL,
  10327. "The target namespace of the included/redefined schema "
  10328. "'%s' has to be absent or the same as the "
  10329. "including/redefining schema's target namespace",
  10330. schemaLocation, NULL);
  10331. goto exit_error;
  10332. }
  10333. bucket->targetNamespace = pctxt->targetNamespace;
  10334. }
  10335. }
  10336. /*
  10337. * Parse the schema.
  10338. */
  10339. if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
  10340. if (isChameleon) {
  10341. /* TODO: Get rid of this flag on the schema itself. */
  10342. if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
  10343. schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10344. } else
  10345. wasChameleon = 1;
  10346. }
  10347. xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10348. /* Restore chameleon flag. */
  10349. if (isChameleon && (!wasChameleon))
  10350. schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10351. }
  10352. /*
  10353. * And now for the children...
  10354. */
  10355. child = node->children;
  10356. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10357. /*
  10358. * Parse (simpleType | complexType | group | attributeGroup))*
  10359. */
  10360. pctxt->redefined = bucket;
  10361. /*
  10362. * How to proceed if the redefined schema was not located?
  10363. */
  10364. pctxt->isRedefine = 1;
  10365. while (IS_SCHEMA(child, "annotation") ||
  10366. IS_SCHEMA(child, "simpleType") ||
  10367. IS_SCHEMA(child, "complexType") ||
  10368. IS_SCHEMA(child, "group") ||
  10369. IS_SCHEMA(child, "attributeGroup")) {
  10370. if (IS_SCHEMA(child, "annotation")) {
  10371. /*
  10372. * TODO: discard or not?
  10373. */
  10374. } else if (IS_SCHEMA(child, "simpleType")) {
  10375. xmlSchemaParseSimpleType(pctxt, schema, child, 1);
  10376. } else if (IS_SCHEMA(child, "complexType")) {
  10377. xmlSchemaParseComplexType(pctxt, schema, child, 1);
  10378. /* hasRedefinitions = 1; */
  10379. } else if (IS_SCHEMA(child, "group")) {
  10380. /* hasRedefinitions = 1; */
  10381. xmlSchemaParseModelGroupDefinition(pctxt,
  10382. schema, child);
  10383. } else if (IS_SCHEMA(child, "attributeGroup")) {
  10384. /* hasRedefinitions = 1; */
  10385. xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
  10386. child);
  10387. }
  10388. child = child->next;
  10389. }
  10390. pctxt->redefined = NULL;
  10391. pctxt->isRedefine = 0;
  10392. } else {
  10393. if (IS_SCHEMA(child, "annotation")) {
  10394. /*
  10395. * TODO: discard or not?
  10396. */
  10397. child = child->next;
  10398. }
  10399. }
  10400. if (child != NULL) {
  10401. res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
  10402. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10403. xmlSchemaPContentErr(pctxt, res,
  10404. NULL, node, child, NULL,
  10405. "(annotation | (simpleType | complexType | group | attributeGroup))*");
  10406. } else {
  10407. xmlSchemaPContentErr(pctxt, res,
  10408. NULL, node, child, NULL,
  10409. "(annotation?)");
  10410. }
  10411. }
  10412. return(res);
  10413. exit_error:
  10414. return(pctxt->err);
  10415. }
  10416. static int
  10417. xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10418. xmlNodePtr node)
  10419. {
  10420. int res;
  10421. #ifndef ENABLE_REDEFINE
  10422. TODO
  10423. return(0);
  10424. #endif
  10425. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10426. XML_SCHEMA_SCHEMA_REDEFINE);
  10427. if (res != 0)
  10428. return(res);
  10429. return(0);
  10430. }
  10431. static int
  10432. xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10433. xmlNodePtr node)
  10434. {
  10435. int res;
  10436. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10437. XML_SCHEMA_SCHEMA_INCLUDE);
  10438. if (res != 0)
  10439. return(res);
  10440. return(0);
  10441. }
  10442. /**
  10443. * xmlSchemaParseModelGroup:
  10444. * @ctxt: a schema validation context
  10445. * @schema: the schema being built
  10446. * @node: a subtree containing XML Schema informations
  10447. * @type: the "compositor" type
  10448. * @particleNeeded: if a a model group with a particle
  10449. *
  10450. * parse a XML schema Sequence definition.
  10451. * Applies parts of:
  10452. * Schema Representation Constraint:
  10453. * Redefinition Constraints and Semantics (src-redefine)
  10454. * (6.1), (6.1.1), (6.1.2)
  10455. *
  10456. * Schema Component Constraint:
  10457. * All Group Limited (cos-all-limited) (2)
  10458. * TODO: Actually this should go to component-level checks,
  10459. * but is done here due to performance. Move it to an other layer
  10460. * is schema construction via an API is implemented.
  10461. *
  10462. * *WARNING* this interface is highly subject to change
  10463. *
  10464. * Returns -1 in case of error, 0 if the declaration is improper and
  10465. * 1 in case of success.
  10466. */
  10467. static xmlSchemaTreeItemPtr
  10468. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10469. xmlNodePtr node, xmlSchemaTypeType type,
  10470. int withParticle)
  10471. {
  10472. xmlSchemaModelGroupPtr item;
  10473. xmlSchemaParticlePtr particle = NULL;
  10474. xmlNodePtr child = NULL;
  10475. xmlAttrPtr attr;
  10476. int min = 1, max = 1, isElemRef, hasRefs = 0;
  10477. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10478. return (NULL);
  10479. /*
  10480. * Create a model group with the given compositor.
  10481. */
  10482. item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
  10483. if (item == NULL)
  10484. return (NULL);
  10485. if (withParticle) {
  10486. if (type == XML_SCHEMA_TYPE_ALL) {
  10487. min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
  10488. max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
  10489. } else {
  10490. /* choice + sequence */
  10491. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  10492. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  10493. "(xs:nonNegativeInteger | unbounded)");
  10494. }
  10495. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  10496. /*
  10497. * Create a particle
  10498. */
  10499. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  10500. if (particle == NULL)
  10501. return (NULL);
  10502. particle->children = (xmlSchemaTreeItemPtr) item;
  10503. /*
  10504. * Check for illegal attributes.
  10505. */
  10506. attr = node->properties;
  10507. while (attr != NULL) {
  10508. if (attr->ns == NULL) {
  10509. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10510. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  10511. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
  10512. xmlSchemaPIllegalAttrErr(ctxt,
  10513. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10514. }
  10515. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10516. xmlSchemaPIllegalAttrErr(ctxt,
  10517. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10518. }
  10519. attr = attr->next;
  10520. }
  10521. } else {
  10522. /*
  10523. * Check for illegal attributes.
  10524. */
  10525. attr = node->properties;
  10526. while (attr != NULL) {
  10527. if (attr->ns == NULL) {
  10528. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  10529. xmlSchemaPIllegalAttrErr(ctxt,
  10530. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10531. }
  10532. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10533. xmlSchemaPIllegalAttrErr(ctxt,
  10534. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10535. }
  10536. attr = attr->next;
  10537. }
  10538. }
  10539. /*
  10540. * Extract and validate attributes.
  10541. */
  10542. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10543. /*
  10544. * And now for the children...
  10545. */
  10546. child = node->children;
  10547. if (IS_SCHEMA(child, "annotation")) {
  10548. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  10549. child = child->next;
  10550. }
  10551. if (type == XML_SCHEMA_TYPE_ALL) {
  10552. xmlSchemaParticlePtr part, last = NULL;
  10553. while (IS_SCHEMA(child, "element")) {
  10554. part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
  10555. schema, child, &isElemRef, 0);
  10556. /*
  10557. * SPEC cos-all-limited (2)
  10558. * "The {max occurs} of all the particles in the {particles}
  10559. * of the ('all') group must be 0 or 1.
  10560. */
  10561. if (part != NULL) {
  10562. if (isElemRef)
  10563. hasRefs++;
  10564. if (part->minOccurs > 1) {
  10565. xmlSchemaPCustomErr(ctxt,
  10566. XML_SCHEMAP_COS_ALL_LIMITED,
  10567. NULL, child,
  10568. "Invalid value for minOccurs (must be 0 or 1)",
  10569. NULL);
  10570. /* Reset to 1. */
  10571. part->minOccurs = 1;
  10572. }
  10573. if (part->maxOccurs > 1) {
  10574. xmlSchemaPCustomErr(ctxt,
  10575. XML_SCHEMAP_COS_ALL_LIMITED,
  10576. NULL, child,
  10577. "Invalid value for maxOccurs (must be 0 or 1)",
  10578. NULL);
  10579. /* Reset to 1. */
  10580. part->maxOccurs = 1;
  10581. }
  10582. if (last == NULL)
  10583. item->children = (xmlSchemaTreeItemPtr) part;
  10584. else
  10585. last->next = (xmlSchemaTreeItemPtr) part;
  10586. last = part;
  10587. }
  10588. child = child->next;
  10589. }
  10590. if (child != NULL) {
  10591. xmlSchemaPContentErr(ctxt,
  10592. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10593. NULL, node, child, NULL,
  10594. "(annotation?, (annotation?, element*)");
  10595. }
  10596. } else {
  10597. /* choice + sequence */
  10598. xmlSchemaTreeItemPtr part = NULL, last = NULL;
  10599. while ((IS_SCHEMA(child, "element")) ||
  10600. (IS_SCHEMA(child, "group")) ||
  10601. (IS_SCHEMA(child, "any")) ||
  10602. (IS_SCHEMA(child, "choice")) ||
  10603. (IS_SCHEMA(child, "sequence"))) {
  10604. if (IS_SCHEMA(child, "element")) {
  10605. part = (xmlSchemaTreeItemPtr)
  10606. xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
  10607. if (part && isElemRef)
  10608. hasRefs++;
  10609. } else if (IS_SCHEMA(child, "group")) {
  10610. part =
  10611. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10612. if (part != NULL)
  10613. hasRefs++;
  10614. /*
  10615. * Handle redefinitions.
  10616. */
  10617. if (ctxt->isRedefine && ctxt->redef &&
  10618. (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
  10619. part && part->children)
  10620. {
  10621. if ((xmlSchemaGetQNameRefName(part->children) ==
  10622. ctxt->redef->refName) &&
  10623. (xmlSchemaGetQNameRefTargetNs(part->children) ==
  10624. ctxt->redef->refTargetNs))
  10625. {
  10626. /*
  10627. * SPEC src-redefine:
  10628. * (6.1) "If it has a <group> among its contents at
  10629. * some level the �actual value� of whose ref
  10630. * [attribute] is the same as the �actual value� of
  10631. * its own name attribute plus target namespace, then
  10632. * all of the following must be true:"
  10633. * (6.1.1) "It must have exactly one such group."
  10634. */
  10635. if (ctxt->redefCounter != 0) {
  10636. xmlChar *str = NULL;
  10637. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10638. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10639. "The redefining model group definition "
  10640. "'%s' must not contain more than one "
  10641. "reference to the redefined definition",
  10642. xmlSchemaFormatQName(&str,
  10643. ctxt->redef->refTargetNs,
  10644. ctxt->redef->refName),
  10645. NULL);
  10646. FREE_AND_NULL(str)
  10647. part = NULL;
  10648. } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
  10649. ((WXS_PARTICLE(part))->maxOccurs != 1))
  10650. {
  10651. xmlChar *str = NULL;
  10652. /*
  10653. * SPEC src-redefine:
  10654. * (6.1.2) "The �actual value� of both that
  10655. * group's minOccurs and maxOccurs [attribute]
  10656. * must be 1 (or �absent�).
  10657. */
  10658. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10659. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10660. "The redefining model group definition "
  10661. "'%s' must not contain a reference to the "
  10662. "redefined definition with a "
  10663. "maxOccurs/minOccurs other than 1",
  10664. xmlSchemaFormatQName(&str,
  10665. ctxt->redef->refTargetNs,
  10666. ctxt->redef->refName),
  10667. NULL);
  10668. FREE_AND_NULL(str)
  10669. part = NULL;
  10670. }
  10671. ctxt->redef->reference = WXS_BASIC_CAST part;
  10672. ctxt->redefCounter++;
  10673. }
  10674. }
  10675. } else if (IS_SCHEMA(child, "any")) {
  10676. part = (xmlSchemaTreeItemPtr)
  10677. xmlSchemaParseAny(ctxt, schema, child);
  10678. } else if (IS_SCHEMA(child, "choice")) {
  10679. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10680. XML_SCHEMA_TYPE_CHOICE, 1);
  10681. } else if (IS_SCHEMA(child, "sequence")) {
  10682. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10683. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10684. }
  10685. if (part != NULL) {
  10686. if (last == NULL)
  10687. item->children = part;
  10688. else
  10689. last->next = part;
  10690. last = part;
  10691. }
  10692. child = child->next;
  10693. }
  10694. if (child != NULL) {
  10695. xmlSchemaPContentErr(ctxt,
  10696. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10697. NULL, node, child, NULL,
  10698. "(annotation?, (element | group | choice | sequence | any)*)");
  10699. }
  10700. }
  10701. if ((max == 0) && (min == 0))
  10702. return (NULL);
  10703. if (hasRefs) {
  10704. /*
  10705. * We need to resolve references.
  10706. */
  10707. WXS_ADD_PENDING(ctxt, item);
  10708. }
  10709. if (withParticle)
  10710. return ((xmlSchemaTreeItemPtr) particle);
  10711. else
  10712. return ((xmlSchemaTreeItemPtr) item);
  10713. }
  10714. /**
  10715. * xmlSchemaParseRestriction:
  10716. * @ctxt: a schema validation context
  10717. * @schema: the schema being built
  10718. * @node: a subtree containing XML Schema informations
  10719. *
  10720. * parse a XML schema Restriction definition
  10721. * *WARNING* this interface is highly subject to change
  10722. *
  10723. * Returns the type definition or NULL in case of error
  10724. */
  10725. static xmlSchemaTypePtr
  10726. xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10727. xmlNodePtr node, xmlSchemaTypeType parentType)
  10728. {
  10729. xmlSchemaTypePtr type;
  10730. xmlNodePtr child = NULL;
  10731. xmlAttrPtr attr;
  10732. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10733. return (NULL);
  10734. /* Not a component, don't create it. */
  10735. type = ctxt->ctxtType;
  10736. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  10737. /*
  10738. * Check for illegal attributes.
  10739. */
  10740. attr = node->properties;
  10741. while (attr != NULL) {
  10742. if (attr->ns == NULL) {
  10743. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10744. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  10745. xmlSchemaPIllegalAttrErr(ctxt,
  10746. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10747. }
  10748. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10749. xmlSchemaPIllegalAttrErr(ctxt,
  10750. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10751. }
  10752. attr = attr->next;
  10753. }
  10754. /*
  10755. * Extract and validate attributes.
  10756. */
  10757. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10758. /*
  10759. * Attribute
  10760. */
  10761. /*
  10762. * Extract the base type. The "base" attribute is mandatory if inside
  10763. * a complex type or if redefining.
  10764. *
  10765. * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
  10766. * among its [children]), the simple type definition which is
  10767. * the {content type} of the type definition �resolved� to by
  10768. * the �actual value� of the base [attribute]"
  10769. */
  10770. if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
  10771. &(type->baseNs), &(type->base)) == 0)
  10772. {
  10773. if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
  10774. xmlSchemaPMissingAttrErr(ctxt,
  10775. XML_SCHEMAP_S4S_ATTR_MISSING,
  10776. NULL, node, "base", NULL);
  10777. } else if ((ctxt->isRedefine) &&
  10778. (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
  10779. {
  10780. if (type->base == NULL) {
  10781. xmlSchemaPMissingAttrErr(ctxt,
  10782. XML_SCHEMAP_S4S_ATTR_MISSING,
  10783. NULL, node, "base", NULL);
  10784. } else if ((! xmlStrEqual(type->base, type->name)) ||
  10785. (! xmlStrEqual(type->baseNs, type->targetNamespace)))
  10786. {
  10787. xmlChar *str1 = NULL, *str2 = NULL;
  10788. /*
  10789. * REDEFINE: SPEC src-redefine (5)
  10790. * "Within the [children], each <simpleType> must have a
  10791. * <restriction> among its [children] ... the �actual value� of
  10792. * whose base [attribute] must be the same as the �actual value�
  10793. * of its own name attribute plus target namespace;"
  10794. */
  10795. xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  10796. NULL, node, "This is a redefinition, but the QName "
  10797. "value '%s' of the 'base' attribute does not match the "
  10798. "type's designation '%s'",
  10799. xmlSchemaFormatQName(&str1, type->baseNs, type->base),
  10800. xmlSchemaFormatQName(&str2, type->targetNamespace,
  10801. type->name), NULL);
  10802. FREE_AND_NULL(str1);
  10803. FREE_AND_NULL(str2);
  10804. /* Avoid confusion and erase the values. */
  10805. type->base = NULL;
  10806. type->baseNs = NULL;
  10807. }
  10808. }
  10809. }
  10810. /*
  10811. * And now for the children...
  10812. */
  10813. child = node->children;
  10814. if (IS_SCHEMA(child, "annotation")) {
  10815. /*
  10816. * Add the annotation to the simple type ancestor.
  10817. */
  10818. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  10819. xmlSchemaParseAnnotation(ctxt, child, 1));
  10820. child = child->next;
  10821. }
  10822. if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
  10823. /*
  10824. * Corresponds to <simpleType><restriction><simpleType>.
  10825. */
  10826. if (IS_SCHEMA(child, "simpleType")) {
  10827. if (type->base != NULL) {
  10828. /*
  10829. * src-restriction-base-or-simpleType
  10830. * Either the base [attribute] or the simpleType [child] of the
  10831. * <restriction> element must be present, but not both.
  10832. */
  10833. xmlSchemaPContentErr(ctxt,
  10834. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10835. NULL, node, child,
  10836. "The attribute 'base' and the <simpleType> child are "
  10837. "mutually exclusive", NULL);
  10838. } else {
  10839. type->baseType = (xmlSchemaTypePtr)
  10840. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10841. }
  10842. child = child->next;
  10843. } else if (type->base == NULL) {
  10844. xmlSchemaPContentErr(ctxt,
  10845. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10846. NULL, node, child,
  10847. "Either the attribute 'base' or a <simpleType> child "
  10848. "must be present", NULL);
  10849. }
  10850. } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10851. /*
  10852. * Corresponds to <complexType><complexContent><restriction>...
  10853. * followed by:
  10854. *
  10855. * Model groups <all>, <choice> and <sequence>.
  10856. */
  10857. if (IS_SCHEMA(child, "all")) {
  10858. type->subtypes = (xmlSchemaTypePtr)
  10859. xmlSchemaParseModelGroup(ctxt, schema, child,
  10860. XML_SCHEMA_TYPE_ALL, 1);
  10861. child = child->next;
  10862. } else if (IS_SCHEMA(child, "choice")) {
  10863. type->subtypes = (xmlSchemaTypePtr)
  10864. xmlSchemaParseModelGroup(ctxt,
  10865. schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
  10866. child = child->next;
  10867. } else if (IS_SCHEMA(child, "sequence")) {
  10868. type->subtypes = (xmlSchemaTypePtr)
  10869. xmlSchemaParseModelGroup(ctxt, schema, child,
  10870. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10871. child = child->next;
  10872. /*
  10873. * Model group reference <group>.
  10874. */
  10875. } else if (IS_SCHEMA(child, "group")) {
  10876. type->subtypes = (xmlSchemaTypePtr)
  10877. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10878. /*
  10879. * Note that the reference will be resolved in
  10880. * xmlSchemaResolveTypeReferences();
  10881. */
  10882. child = child->next;
  10883. }
  10884. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10885. /*
  10886. * Corresponds to <complexType><simpleContent><restriction>...
  10887. *
  10888. * "1.1 the simple type definition corresponding to the <simpleType>
  10889. * among the [children] of <restriction> if there is one;"
  10890. */
  10891. if (IS_SCHEMA(child, "simpleType")) {
  10892. /*
  10893. * We will store the to-be-restricted simple type in
  10894. * type->contentTypeDef *temporarily*.
  10895. */
  10896. type->contentTypeDef = (xmlSchemaTypePtr)
  10897. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10898. if ( type->contentTypeDef == NULL)
  10899. return (NULL);
  10900. child = child->next;
  10901. }
  10902. }
  10903. if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
  10904. (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
  10905. xmlSchemaFacetPtr facet, lastfacet = NULL;
  10906. /*
  10907. * Corresponds to <complexType><simpleContent><restriction>...
  10908. * <simpleType><restriction>...
  10909. */
  10910. /*
  10911. * Add the facets to the simple type ancestor.
  10912. */
  10913. /*
  10914. * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
  10915. * Simple Type Definition Schema Representation Constraint:
  10916. * *Single Facet Value*
  10917. */
  10918. while ((IS_SCHEMA(child, "minInclusive")) ||
  10919. (IS_SCHEMA(child, "minExclusive")) ||
  10920. (IS_SCHEMA(child, "maxInclusive")) ||
  10921. (IS_SCHEMA(child, "maxExclusive")) ||
  10922. (IS_SCHEMA(child, "totalDigits")) ||
  10923. (IS_SCHEMA(child, "fractionDigits")) ||
  10924. (IS_SCHEMA(child, "pattern")) ||
  10925. (IS_SCHEMA(child, "enumeration")) ||
  10926. (IS_SCHEMA(child, "whiteSpace")) ||
  10927. (IS_SCHEMA(child, "length")) ||
  10928. (IS_SCHEMA(child, "maxLength")) ||
  10929. (IS_SCHEMA(child, "minLength"))) {
  10930. facet = xmlSchemaParseFacet(ctxt, schema, child);
  10931. if (facet != NULL) {
  10932. if (lastfacet == NULL)
  10933. type->facets = facet;
  10934. else
  10935. lastfacet->next = facet;
  10936. lastfacet = facet;
  10937. lastfacet->next = NULL;
  10938. }
  10939. child = child->next;
  10940. }
  10941. /*
  10942. * Create links for derivation and validation.
  10943. */
  10944. if (type->facets != NULL) {
  10945. xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
  10946. facet = type->facets;
  10947. do {
  10948. facetLink = (xmlSchemaFacetLinkPtr)
  10949. xmlMalloc(sizeof(xmlSchemaFacetLink));
  10950. if (facetLink == NULL) {
  10951. xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
  10952. xmlFree(facetLink);
  10953. return (NULL);
  10954. }
  10955. facetLink->facet = facet;
  10956. facetLink->next = NULL;
  10957. if (lastFacetLink == NULL)
  10958. type->facetSet = facetLink;
  10959. else
  10960. lastFacetLink->next = facetLink;
  10961. lastFacetLink = facetLink;
  10962. facet = facet->next;
  10963. } while (facet != NULL);
  10964. }
  10965. }
  10966. if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
  10967. /*
  10968. * Attribute uses/declarations.
  10969. */
  10970. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  10971. (xmlSchemaItemListPtr *) &(type->attrUses),
  10972. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  10973. return(NULL);
  10974. /*
  10975. * Attribute wildcard.
  10976. */
  10977. if (IS_SCHEMA(child, "anyAttribute")) {
  10978. type->attributeWildcard =
  10979. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  10980. child = child->next;
  10981. }
  10982. }
  10983. if (child != NULL) {
  10984. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10985. xmlSchemaPContentErr(ctxt,
  10986. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10987. NULL, node, child, NULL,
  10988. "annotation?, (group | all | choice | sequence)?, "
  10989. "((attribute | attributeGroup)*, anyAttribute?))");
  10990. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10991. xmlSchemaPContentErr(ctxt,
  10992. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10993. NULL, node, child, NULL,
  10994. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  10995. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  10996. "length | minLength | maxLength | enumeration | whiteSpace | "
  10997. "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
  10998. } else {
  10999. /* Simple type */
  11000. xmlSchemaPContentErr(ctxt,
  11001. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11002. NULL, node, child, NULL,
  11003. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11004. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11005. "length | minLength | maxLength | enumeration | whiteSpace | "
  11006. "pattern)*))");
  11007. }
  11008. }
  11009. return (NULL);
  11010. }
  11011. /**
  11012. * xmlSchemaParseExtension:
  11013. * @ctxt: a schema validation context
  11014. * @schema: the schema being built
  11015. * @node: a subtree containing XML Schema informations
  11016. *
  11017. * Parses an <extension>, which is found inside a
  11018. * <simpleContent> or <complexContent>.
  11019. * *WARNING* this interface is highly subject to change.
  11020. *
  11021. * TODO: Returns the type definition or NULL in case of error
  11022. */
  11023. static xmlSchemaTypePtr
  11024. xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11025. xmlNodePtr node, xmlSchemaTypeType parentType)
  11026. {
  11027. xmlSchemaTypePtr type;
  11028. xmlNodePtr child = NULL;
  11029. xmlAttrPtr attr;
  11030. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11031. return (NULL);
  11032. /* Not a component, don't create it. */
  11033. type = ctxt->ctxtType;
  11034. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
  11035. /*
  11036. * Check for illegal attributes.
  11037. */
  11038. attr = node->properties;
  11039. while (attr != NULL) {
  11040. if (attr->ns == NULL) {
  11041. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11042. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  11043. xmlSchemaPIllegalAttrErr(ctxt,
  11044. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11045. }
  11046. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11047. xmlSchemaPIllegalAttrErr(ctxt,
  11048. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11049. }
  11050. attr = attr->next;
  11051. }
  11052. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11053. /*
  11054. * Attribute "base" - mandatory.
  11055. */
  11056. if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
  11057. "base", &(type->baseNs), &(type->base)) == 0) &&
  11058. (type->base == NULL)) {
  11059. xmlSchemaPMissingAttrErr(ctxt,
  11060. XML_SCHEMAP_S4S_ATTR_MISSING,
  11061. NULL, node, "base", NULL);
  11062. }
  11063. /*
  11064. * And now for the children...
  11065. */
  11066. child = node->children;
  11067. if (IS_SCHEMA(child, "annotation")) {
  11068. /*
  11069. * Add the annotation to the type ancestor.
  11070. */
  11071. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11072. xmlSchemaParseAnnotation(ctxt, child, 1));
  11073. child = child->next;
  11074. }
  11075. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11076. /*
  11077. * Corresponds to <complexType><complexContent><extension>... and:
  11078. *
  11079. * Model groups <all>, <choice>, <sequence> and <group>.
  11080. */
  11081. if (IS_SCHEMA(child, "all")) {
  11082. type->subtypes = (xmlSchemaTypePtr)
  11083. xmlSchemaParseModelGroup(ctxt, schema,
  11084. child, XML_SCHEMA_TYPE_ALL, 1);
  11085. child = child->next;
  11086. } else if (IS_SCHEMA(child, "choice")) {
  11087. type->subtypes = (xmlSchemaTypePtr)
  11088. xmlSchemaParseModelGroup(ctxt, schema,
  11089. child, XML_SCHEMA_TYPE_CHOICE, 1);
  11090. child = child->next;
  11091. } else if (IS_SCHEMA(child, "sequence")) {
  11092. type->subtypes = (xmlSchemaTypePtr)
  11093. xmlSchemaParseModelGroup(ctxt, schema,
  11094. child, XML_SCHEMA_TYPE_SEQUENCE, 1);
  11095. child = child->next;
  11096. } else if (IS_SCHEMA(child, "group")) {
  11097. type->subtypes = (xmlSchemaTypePtr)
  11098. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11099. /*
  11100. * Note that the reference will be resolved in
  11101. * xmlSchemaResolveTypeReferences();
  11102. */
  11103. child = child->next;
  11104. }
  11105. }
  11106. if (child != NULL) {
  11107. /*
  11108. * Attribute uses/declarations.
  11109. */
  11110. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11111. (xmlSchemaItemListPtr *) &(type->attrUses),
  11112. XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
  11113. return(NULL);
  11114. /*
  11115. * Attribute wildcard.
  11116. */
  11117. if (IS_SCHEMA(child, "anyAttribute")) {
  11118. ctxt->ctxtType->attributeWildcard =
  11119. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11120. child = child->next;
  11121. }
  11122. }
  11123. if (child != NULL) {
  11124. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11125. /* Complex content extension. */
  11126. xmlSchemaPContentErr(ctxt,
  11127. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11128. NULL, node, child, NULL,
  11129. "(annotation?, ((group | all | choice | sequence)?, "
  11130. "((attribute | attributeGroup)*, anyAttribute?)))");
  11131. } else {
  11132. /* Simple content extension. */
  11133. xmlSchemaPContentErr(ctxt,
  11134. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11135. NULL, node, child, NULL,
  11136. "(annotation?, ((attribute | attributeGroup)*, "
  11137. "anyAttribute?))");
  11138. }
  11139. }
  11140. return (NULL);
  11141. }
  11142. /**
  11143. * xmlSchemaParseSimpleContent:
  11144. * @ctxt: a schema validation context
  11145. * @schema: the schema being built
  11146. * @node: a subtree containing XML Schema informations
  11147. *
  11148. * parse a XML schema SimpleContent definition
  11149. * *WARNING* this interface is highly subject to change
  11150. *
  11151. * Returns the type definition or NULL in case of error
  11152. */
  11153. static int
  11154. xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
  11155. xmlSchemaPtr schema, xmlNodePtr node,
  11156. int *hasRestrictionOrExtension)
  11157. {
  11158. xmlSchemaTypePtr type;
  11159. xmlNodePtr child = NULL;
  11160. xmlAttrPtr attr;
  11161. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11162. (hasRestrictionOrExtension == NULL))
  11163. return (-1);
  11164. *hasRestrictionOrExtension = 0;
  11165. /* Not a component, don't create it. */
  11166. type = ctxt->ctxtType;
  11167. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  11168. /*
  11169. * Check for illegal attributes.
  11170. */
  11171. attr = node->properties;
  11172. while (attr != NULL) {
  11173. if (attr->ns == NULL) {
  11174. if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  11175. xmlSchemaPIllegalAttrErr(ctxt,
  11176. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11177. }
  11178. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11179. xmlSchemaPIllegalAttrErr(ctxt,
  11180. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11181. }
  11182. attr = attr->next;
  11183. }
  11184. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11185. /*
  11186. * And now for the children...
  11187. */
  11188. child = node->children;
  11189. if (IS_SCHEMA(child, "annotation")) {
  11190. /*
  11191. * Add the annotation to the complex type ancestor.
  11192. */
  11193. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11194. xmlSchemaParseAnnotation(ctxt, child, 1));
  11195. child = child->next;
  11196. }
  11197. if (child == NULL) {
  11198. xmlSchemaPContentErr(ctxt,
  11199. XML_SCHEMAP_S4S_ELEM_MISSING,
  11200. NULL, node, NULL, NULL,
  11201. "(annotation?, (restriction | extension))");
  11202. }
  11203. if (child == NULL) {
  11204. xmlSchemaPContentErr(ctxt,
  11205. XML_SCHEMAP_S4S_ELEM_MISSING,
  11206. NULL, node, NULL, NULL,
  11207. "(annotation?, (restriction | extension))");
  11208. }
  11209. if (IS_SCHEMA(child, "restriction")) {
  11210. xmlSchemaParseRestriction(ctxt, schema, child,
  11211. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11212. (*hasRestrictionOrExtension) = 1;
  11213. child = child->next;
  11214. } else if (IS_SCHEMA(child, "extension")) {
  11215. xmlSchemaParseExtension(ctxt, schema, child,
  11216. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11217. (*hasRestrictionOrExtension) = 1;
  11218. child = child->next;
  11219. }
  11220. if (child != NULL) {
  11221. xmlSchemaPContentErr(ctxt,
  11222. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11223. NULL, node, child, NULL,
  11224. "(annotation?, (restriction | extension))");
  11225. }
  11226. return (0);
  11227. }
  11228. /**
  11229. * xmlSchemaParseComplexContent:
  11230. * @ctxt: a schema validation context
  11231. * @schema: the schema being built
  11232. * @node: a subtree containing XML Schema informations
  11233. *
  11234. * parse a XML schema ComplexContent definition
  11235. * *WARNING* this interface is highly subject to change
  11236. *
  11237. * Returns the type definition or NULL in case of error
  11238. */
  11239. static int
  11240. xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
  11241. xmlSchemaPtr schema, xmlNodePtr node,
  11242. int *hasRestrictionOrExtension)
  11243. {
  11244. xmlSchemaTypePtr type;
  11245. xmlNodePtr child = NULL;
  11246. xmlAttrPtr attr;
  11247. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11248. (hasRestrictionOrExtension == NULL))
  11249. return (-1);
  11250. *hasRestrictionOrExtension = 0;
  11251. /* Not a component, don't create it. */
  11252. type = ctxt->ctxtType;
  11253. /*
  11254. * Check for illegal attributes.
  11255. */
  11256. attr = node->properties;
  11257. while (attr != NULL) {
  11258. if (attr->ns == NULL) {
  11259. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11260. (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
  11261. {
  11262. xmlSchemaPIllegalAttrErr(ctxt,
  11263. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11264. }
  11265. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11266. xmlSchemaPIllegalAttrErr(ctxt,
  11267. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11268. }
  11269. attr = attr->next;
  11270. }
  11271. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11272. /*
  11273. * Set the 'mixed' on the complex type ancestor.
  11274. */
  11275. if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
  11276. if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
  11277. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11278. }
  11279. child = node->children;
  11280. if (IS_SCHEMA(child, "annotation")) {
  11281. /*
  11282. * Add the annotation to the complex type ancestor.
  11283. */
  11284. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11285. xmlSchemaParseAnnotation(ctxt, child, 1));
  11286. child = child->next;
  11287. }
  11288. if (child == NULL) {
  11289. xmlSchemaPContentErr(ctxt,
  11290. XML_SCHEMAP_S4S_ELEM_MISSING,
  11291. NULL, node, NULL,
  11292. NULL, "(annotation?, (restriction | extension))");
  11293. }
  11294. if (child == NULL) {
  11295. xmlSchemaPContentErr(ctxt,
  11296. XML_SCHEMAP_S4S_ELEM_MISSING,
  11297. NULL, node, NULL,
  11298. NULL, "(annotation?, (restriction | extension))");
  11299. }
  11300. if (IS_SCHEMA(child, "restriction")) {
  11301. xmlSchemaParseRestriction(ctxt, schema, child,
  11302. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11303. (*hasRestrictionOrExtension) = 1;
  11304. child = child->next;
  11305. } else if (IS_SCHEMA(child, "extension")) {
  11306. xmlSchemaParseExtension(ctxt, schema, child,
  11307. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11308. (*hasRestrictionOrExtension) = 1;
  11309. child = child->next;
  11310. }
  11311. if (child != NULL) {
  11312. xmlSchemaPContentErr(ctxt,
  11313. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11314. NULL, node, child,
  11315. NULL, "(annotation?, (restriction | extension))");
  11316. }
  11317. return (0);
  11318. }
  11319. /**
  11320. * xmlSchemaParseComplexType:
  11321. * @ctxt: a schema validation context
  11322. * @schema: the schema being built
  11323. * @node: a subtree containing XML Schema informations
  11324. *
  11325. * parse a XML schema Complex Type definition
  11326. * *WARNING* this interface is highly subject to change
  11327. *
  11328. * Returns the type definition or NULL in case of error
  11329. */
  11330. static xmlSchemaTypePtr
  11331. xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11332. xmlNodePtr node, int topLevel)
  11333. {
  11334. xmlSchemaTypePtr type, ctxtType;
  11335. xmlNodePtr child = NULL;
  11336. const xmlChar *name = NULL;
  11337. xmlAttrPtr attr;
  11338. const xmlChar *attrValue;
  11339. #ifdef ENABLE_NAMED_LOCALS
  11340. char buf[40];
  11341. #endif
  11342. int final = 0, block = 0, hasRestrictionOrExtension = 0;
  11343. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11344. return (NULL);
  11345. ctxtType = ctxt->ctxtType;
  11346. if (topLevel) {
  11347. attr = xmlSchemaGetPropNode(node, "name");
  11348. if (attr == NULL) {
  11349. xmlSchemaPMissingAttrErr(ctxt,
  11350. XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
  11351. return (NULL);
  11352. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  11353. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  11354. return (NULL);
  11355. }
  11356. }
  11357. if (topLevel == 0) {
  11358. /*
  11359. * Parse as local complex type definition.
  11360. */
  11361. #ifdef ENABLE_NAMED_LOCALS
  11362. snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
  11363. type = xmlSchemaAddType(ctxt, schema,
  11364. XML_SCHEMA_TYPE_COMPLEX,
  11365. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  11366. ctxt->targetNamespace, node, 0);
  11367. #else
  11368. type = xmlSchemaAddType(ctxt, schema,
  11369. XML_SCHEMA_TYPE_COMPLEX,
  11370. NULL, ctxt->targetNamespace, node, 0);
  11371. #endif
  11372. if (type == NULL)
  11373. return (NULL);
  11374. name = type->name;
  11375. type->node = node;
  11376. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11377. /*
  11378. * TODO: We need the target namespace.
  11379. */
  11380. } else {
  11381. /*
  11382. * Parse as global complex type definition.
  11383. */
  11384. type = xmlSchemaAddType(ctxt, schema,
  11385. XML_SCHEMA_TYPE_COMPLEX,
  11386. name, ctxt->targetNamespace, node, 1);
  11387. if (type == NULL)
  11388. return (NULL);
  11389. type->node = node;
  11390. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11391. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  11392. }
  11393. type->targetNamespace = ctxt->targetNamespace;
  11394. /*
  11395. * Handle attributes.
  11396. */
  11397. attr = node->properties;
  11398. while (attr != NULL) {
  11399. if (attr->ns == NULL) {
  11400. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  11401. /*
  11402. * Attribute "id".
  11403. */
  11404. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11405. } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
  11406. /*
  11407. * Attribute "mixed".
  11408. */
  11409. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11410. NULL, (xmlNodePtr) attr))
  11411. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11412. } else if (topLevel) {
  11413. /*
  11414. * Attributes of global complex type definitions.
  11415. */
  11416. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  11417. /* Pass. */
  11418. } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
  11419. /*
  11420. * Attribute "abstract".
  11421. */
  11422. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11423. NULL, (xmlNodePtr) attr))
  11424. type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
  11425. } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
  11426. /*
  11427. * Attribute "final".
  11428. */
  11429. attrValue = xmlSchemaGetNodeContent(ctxt,
  11430. (xmlNodePtr) attr);
  11431. if (xmlSchemaPValAttrBlockFinal(attrValue,
  11432. &(type->flags),
  11433. -1,
  11434. XML_SCHEMAS_TYPE_FINAL_EXTENSION,
  11435. XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
  11436. -1, -1, -1) != 0)
  11437. {
  11438. xmlSchemaPSimpleTypeErr(ctxt,
  11439. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11440. NULL, (xmlNodePtr) attr, NULL,
  11441. "(#all | List of (extension | restriction))",
  11442. attrValue, NULL, NULL, NULL);
  11443. } else
  11444. final = 1;
  11445. } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
  11446. /*
  11447. * Attribute "block".
  11448. */
  11449. attrValue = xmlSchemaGetNodeContent(ctxt,
  11450. (xmlNodePtr) attr);
  11451. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  11452. -1,
  11453. XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
  11454. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
  11455. -1, -1, -1) != 0) {
  11456. xmlSchemaPSimpleTypeErr(ctxt,
  11457. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11458. NULL, (xmlNodePtr) attr, NULL,
  11459. "(#all | List of (extension | restriction)) ",
  11460. attrValue, NULL, NULL, NULL);
  11461. } else
  11462. block = 1;
  11463. } else {
  11464. xmlSchemaPIllegalAttrErr(ctxt,
  11465. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11466. }
  11467. } else {
  11468. xmlSchemaPIllegalAttrErr(ctxt,
  11469. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11470. }
  11471. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11472. xmlSchemaPIllegalAttrErr(ctxt,
  11473. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11474. }
  11475. attr = attr->next;
  11476. }
  11477. if (! block) {
  11478. /*
  11479. * Apply default "block" values.
  11480. */
  11481. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  11482. type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  11483. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  11484. type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  11485. }
  11486. if (! final) {
  11487. /*
  11488. * Apply default "block" values.
  11489. */
  11490. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  11491. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  11492. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  11493. type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
  11494. }
  11495. /*
  11496. * And now for the children...
  11497. */
  11498. child = node->children;
  11499. if (IS_SCHEMA(child, "annotation")) {
  11500. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  11501. child = child->next;
  11502. }
  11503. ctxt->ctxtType = type;
  11504. if (IS_SCHEMA(child, "simpleContent")) {
  11505. /*
  11506. * <complexType><simpleContent>...
  11507. * 3.4.3 : 2.2
  11508. * Specifying mixed='true' when the <simpleContent>
  11509. * alternative is chosen has no effect
  11510. */
  11511. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  11512. type->flags ^= XML_SCHEMAS_TYPE_MIXED;
  11513. xmlSchemaParseSimpleContent(ctxt, schema, child,
  11514. &hasRestrictionOrExtension);
  11515. child = child->next;
  11516. } else if (IS_SCHEMA(child, "complexContent")) {
  11517. /*
  11518. * <complexType><complexContent>...
  11519. */
  11520. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  11521. xmlSchemaParseComplexContent(ctxt, schema, child,
  11522. &hasRestrictionOrExtension);
  11523. child = child->next;
  11524. } else {
  11525. /*
  11526. * E.g <complexType><sequence>... or <complexType><attribute>... etc.
  11527. *
  11528. * SPEC
  11529. * "...the third alternative (neither <simpleContent> nor
  11530. * <complexContent>) is chosen. This case is understood as shorthand
  11531. * for complex content restricting the �ur-type definition�, and the
  11532. * details of the mappings should be modified as necessary.
  11533. */
  11534. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  11535. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  11536. /*
  11537. * Parse model groups.
  11538. */
  11539. if (IS_SCHEMA(child, "all")) {
  11540. type->subtypes = (xmlSchemaTypePtr)
  11541. xmlSchemaParseModelGroup(ctxt, schema, child,
  11542. XML_SCHEMA_TYPE_ALL, 1);
  11543. child = child->next;
  11544. } else if (IS_SCHEMA(child, "choice")) {
  11545. type->subtypes = (xmlSchemaTypePtr)
  11546. xmlSchemaParseModelGroup(ctxt, schema, child,
  11547. XML_SCHEMA_TYPE_CHOICE, 1);
  11548. child = child->next;
  11549. } else if (IS_SCHEMA(child, "sequence")) {
  11550. type->subtypes = (xmlSchemaTypePtr)
  11551. xmlSchemaParseModelGroup(ctxt, schema, child,
  11552. XML_SCHEMA_TYPE_SEQUENCE, 1);
  11553. child = child->next;
  11554. } else if (IS_SCHEMA(child, "group")) {
  11555. type->subtypes = (xmlSchemaTypePtr)
  11556. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11557. /*
  11558. * Note that the reference will be resolved in
  11559. * xmlSchemaResolveTypeReferences();
  11560. */
  11561. child = child->next;
  11562. }
  11563. /*
  11564. * Parse attribute decls/refs.
  11565. */
  11566. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11567. (xmlSchemaItemListPtr *) &(type->attrUses),
  11568. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11569. return(NULL);
  11570. /*
  11571. * Parse attribute wildcard.
  11572. */
  11573. if (IS_SCHEMA(child, "anyAttribute")) {
  11574. type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11575. child = child->next;
  11576. }
  11577. }
  11578. if (child != NULL) {
  11579. xmlSchemaPContentErr(ctxt,
  11580. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11581. NULL, node, child,
  11582. NULL, "(annotation?, (simpleContent | complexContent | "
  11583. "((group | all | choice | sequence)?, ((attribute | "
  11584. "attributeGroup)*, anyAttribute?))))");
  11585. }
  11586. /*
  11587. * REDEFINE: SPEC src-redefine (5)
  11588. */
  11589. if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
  11590. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  11591. NULL, node, "This is a redefinition, thus the "
  11592. "<complexType> must have a <restriction> or <extension> "
  11593. "grand-child", NULL);
  11594. }
  11595. ctxt->ctxtType = ctxtType;
  11596. return (type);
  11597. }
  11598. /************************************************************************
  11599. * *
  11600. * Validating using Schemas *
  11601. * *
  11602. ************************************************************************/
  11603. /************************************************************************
  11604. * *
  11605. * Reading/Writing Schemas *
  11606. * *
  11607. ************************************************************************/
  11608. #if 0 /* Will be enabled if it is clear what options are needed. */
  11609. /**
  11610. * xmlSchemaParserCtxtSetOptions:
  11611. * @ctxt: a schema parser context
  11612. * @options: a combination of xmlSchemaParserOption
  11613. *
  11614. * Sets the options to be used during the parse.
  11615. *
  11616. * Returns 0 in case of success, -1 in case of an
  11617. * API error.
  11618. */
  11619. static int
  11620. xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
  11621. int options)
  11622. {
  11623. int i;
  11624. if (ctxt == NULL)
  11625. return (-1);
  11626. /*
  11627. * WARNING: Change the start value if adding to the
  11628. * xmlSchemaParseOption.
  11629. */
  11630. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  11631. if (options & 1<<i) {
  11632. return (-1);
  11633. }
  11634. }
  11635. ctxt->options = options;
  11636. return (0);
  11637. }
  11638. /**
  11639. * xmlSchemaValidCtxtGetOptions:
  11640. * @ctxt: a schema parser context
  11641. *
  11642. * Returns the option combination of the parser context.
  11643. */
  11644. static int
  11645. xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
  11646. {
  11647. if (ctxt == NULL)
  11648. return (-1);
  11649. else
  11650. return (ctxt->options);
  11651. }
  11652. #endif
  11653. /**
  11654. * xmlSchemaNewParserCtxt:
  11655. * @URL: the location of the schema
  11656. *
  11657. * Create an XML Schemas parse context for that file/resource expected
  11658. * to contain an XML Schemas file.
  11659. *
  11660. * Returns the parser context or NULL in case of error
  11661. */
  11662. xmlSchemaParserCtxtPtr
  11663. xmlSchemaNewParserCtxt(const char *URL)
  11664. {
  11665. xmlSchemaParserCtxtPtr ret;
  11666. if (URL == NULL)
  11667. return (NULL);
  11668. ret = xmlSchemaParserCtxtCreate();
  11669. if (ret == NULL)
  11670. return(NULL);
  11671. ret->dict = xmlDictCreate();
  11672. ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
  11673. return (ret);
  11674. }
  11675. /**
  11676. * xmlSchemaNewMemParserCtxt:
  11677. * @buffer: a pointer to a char array containing the schemas
  11678. * @size: the size of the array
  11679. *
  11680. * Create an XML Schemas parse context for that memory buffer expected
  11681. * to contain an XML Schemas file.
  11682. *
  11683. * Returns the parser context or NULL in case of error
  11684. */
  11685. xmlSchemaParserCtxtPtr
  11686. xmlSchemaNewMemParserCtxt(const char *buffer, int size)
  11687. {
  11688. xmlSchemaParserCtxtPtr ret;
  11689. if ((buffer == NULL) || (size <= 0))
  11690. return (NULL);
  11691. ret = xmlSchemaParserCtxtCreate();
  11692. if (ret == NULL)
  11693. return(NULL);
  11694. ret->buffer = buffer;
  11695. ret->size = size;
  11696. ret->dict = xmlDictCreate();
  11697. return (ret);
  11698. }
  11699. /**
  11700. * xmlSchemaNewDocParserCtxt:
  11701. * @doc: a preparsed document tree
  11702. *
  11703. * Create an XML Schemas parse context for that document.
  11704. * NB. The document may be modified during the parsing process.
  11705. *
  11706. * Returns the parser context or NULL in case of error
  11707. */
  11708. xmlSchemaParserCtxtPtr
  11709. xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
  11710. {
  11711. xmlSchemaParserCtxtPtr ret;
  11712. if (doc == NULL)
  11713. return (NULL);
  11714. ret = xmlSchemaParserCtxtCreate();
  11715. if (ret == NULL)
  11716. return(NULL);
  11717. ret->doc = doc;
  11718. ret->dict = xmlDictCreate();
  11719. /* The application has responsibility for the document */
  11720. ret->preserve = 1;
  11721. return (ret);
  11722. }
  11723. /**
  11724. * xmlSchemaFreeParserCtxt:
  11725. * @ctxt: the schema parser context
  11726. *
  11727. * Free the resources associated to the schema parser context
  11728. */
  11729. void
  11730. xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
  11731. {
  11732. if (ctxt == NULL)
  11733. return;
  11734. if (ctxt->doc != NULL && !ctxt->preserve)
  11735. xmlFreeDoc(ctxt->doc);
  11736. if (ctxt->vctxt != NULL) {
  11737. xmlSchemaFreeValidCtxt(ctxt->vctxt);
  11738. }
  11739. if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
  11740. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  11741. ctxt->constructor = NULL;
  11742. ctxt->ownsConstructor = 0;
  11743. }
  11744. if (ctxt->attrProhibs != NULL)
  11745. xmlSchemaItemListFree(ctxt->attrProhibs);
  11746. xmlDictFree(ctxt->dict);
  11747. xmlFree(ctxt);
  11748. }
  11749. /************************************************************************
  11750. * *
  11751. * Building the content models *
  11752. * *
  11753. ************************************************************************/
  11754. /**
  11755. * xmlSchemaBuildContentModelForSubstGroup:
  11756. *
  11757. * Returns 1 if nillable, 0 otherwise
  11758. */
  11759. static int
  11760. xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
  11761. xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
  11762. {
  11763. xmlAutomataStatePtr start, tmp;
  11764. xmlSchemaElementPtr elemDecl, member;
  11765. xmlSchemaSubstGroupPtr substGroup;
  11766. int i;
  11767. int ret = 0;
  11768. elemDecl = (xmlSchemaElementPtr) particle->children;
  11769. /*
  11770. * Wrap the substitution group with a CHOICE.
  11771. */
  11772. start = pctxt->state;
  11773. if (end == NULL)
  11774. end = xmlAutomataNewState(pctxt->am);
  11775. substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
  11776. if (substGroup == NULL) {
  11777. xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
  11778. XML_SCHEMAP_INTERNAL,
  11779. "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
  11780. "declaration is marked having a subst. group but none "
  11781. "available.\n", elemDecl->name, NULL);
  11782. return(0);
  11783. }
  11784. if (counter >= 0) {
  11785. /*
  11786. * NOTE that we put the declaration in, even if it's abstract.
  11787. * However, an error will be raised during *validation* if an element
  11788. * information item shall be validated against an abstract element
  11789. * declaration.
  11790. */
  11791. tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
  11792. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11793. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11794. /*
  11795. * Add subst. group members.
  11796. */
  11797. for (i = 0; i < substGroup->members->nbItems; i++) {
  11798. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11799. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11800. member->name, member->targetNamespace, member);
  11801. }
  11802. } else if (particle->maxOccurs == 1) {
  11803. /*
  11804. * NOTE that we put the declaration in, even if it's abstract,
  11805. */
  11806. xmlAutomataNewEpsilon(pctxt->am,
  11807. xmlAutomataNewTransition2(pctxt->am,
  11808. start, NULL,
  11809. elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
  11810. /*
  11811. * Add subst. group members.
  11812. */
  11813. for (i = 0; i < substGroup->members->nbItems; i++) {
  11814. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11815. /*
  11816. * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
  11817. * was incorrectly used instead of xmlAutomataNewTransition2()
  11818. * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
  11819. * section in xmlSchemaBuildAContentModel() ).
  11820. * TODO: Check if xmlAutomataNewOnceTrans2() was instead
  11821. * intended for the above "counter" section originally. I.e.,
  11822. * check xs:all with subst-groups.
  11823. *
  11824. * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
  11825. * member->name, member->targetNamespace,
  11826. * 1, 1, member);
  11827. */
  11828. tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
  11829. member->name, member->targetNamespace, member);
  11830. xmlAutomataNewEpsilon(pctxt->am, tmp, end);
  11831. }
  11832. } else {
  11833. xmlAutomataStatePtr hop;
  11834. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11835. UNBOUNDED : particle->maxOccurs - 1;
  11836. int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11837. counter =
  11838. xmlAutomataNewCounter(pctxt->am, minOccurs,
  11839. maxOccurs);
  11840. hop = xmlAutomataNewState(pctxt->am);
  11841. xmlAutomataNewEpsilon(pctxt->am,
  11842. xmlAutomataNewTransition2(pctxt->am,
  11843. start, NULL,
  11844. elemDecl->name, elemDecl->targetNamespace, elemDecl),
  11845. hop);
  11846. /*
  11847. * Add subst. group members.
  11848. */
  11849. for (i = 0; i < substGroup->members->nbItems; i++) {
  11850. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11851. xmlAutomataNewEpsilon(pctxt->am,
  11852. xmlAutomataNewTransition2(pctxt->am,
  11853. start, NULL,
  11854. member->name, member->targetNamespace, member),
  11855. hop);
  11856. }
  11857. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  11858. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  11859. }
  11860. if (particle->minOccurs == 0) {
  11861. xmlAutomataNewEpsilon(pctxt->am, start, end);
  11862. ret = 1;
  11863. }
  11864. pctxt->state = end;
  11865. return(ret);
  11866. }
  11867. /**
  11868. * xmlSchemaBuildContentModelForElement:
  11869. *
  11870. * Returns 1 if nillable, 0 otherwise
  11871. */
  11872. static int
  11873. xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
  11874. xmlSchemaParticlePtr particle)
  11875. {
  11876. int ret = 0;
  11877. if (((xmlSchemaElementPtr) particle->children)->flags &
  11878. XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  11879. /*
  11880. * Substitution groups.
  11881. */
  11882. ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
  11883. } else {
  11884. xmlSchemaElementPtr elemDecl;
  11885. xmlAutomataStatePtr start;
  11886. elemDecl = (xmlSchemaElementPtr) particle->children;
  11887. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  11888. return(0);
  11889. if (particle->maxOccurs == 1) {
  11890. start = ctxt->state;
  11891. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11892. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11893. } else if ((particle->maxOccurs >= UNBOUNDED) &&
  11894. (particle->minOccurs < 2)) {
  11895. /* Special case. */
  11896. start = ctxt->state;
  11897. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11898. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11899. ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
  11900. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11901. } else {
  11902. int counter;
  11903. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11904. UNBOUNDED : particle->maxOccurs - 1;
  11905. int minOccurs = particle->minOccurs < 1 ?
  11906. 0 : particle->minOccurs - 1;
  11907. start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  11908. counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
  11909. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11910. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11911. xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
  11912. ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
  11913. NULL, counter);
  11914. }
  11915. if (particle->minOccurs == 0) {
  11916. xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
  11917. ret = 1;
  11918. }
  11919. }
  11920. return(ret);
  11921. }
  11922. /**
  11923. * xmlSchemaBuildAContentModel:
  11924. * @ctxt: the schema parser context
  11925. * @particle: the particle component
  11926. * @name: the complex type's name whose content is being built
  11927. *
  11928. * Create the automaton for the {content type} of a complex type.
  11929. *
  11930. * Returns 1 if the content is nillable, 0 otherwise
  11931. */
  11932. static int
  11933. xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
  11934. xmlSchemaParticlePtr particle)
  11935. {
  11936. int ret = 0, tmp2;
  11937. if (particle == NULL) {
  11938. PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
  11939. return(1);
  11940. }
  11941. if (particle->children == NULL) {
  11942. /*
  11943. * Just return in this case. A missing "term" of the particle
  11944. * might arise due to an invalid "term" component.
  11945. */
  11946. return(1);
  11947. }
  11948. switch (particle->children->type) {
  11949. case XML_SCHEMA_TYPE_ANY: {
  11950. xmlAutomataStatePtr start, end;
  11951. xmlSchemaWildcardPtr wild;
  11952. xmlSchemaWildcardNsPtr ns;
  11953. wild = (xmlSchemaWildcardPtr) particle->children;
  11954. start = pctxt->state;
  11955. end = xmlAutomataNewState(pctxt->am);
  11956. if (particle->maxOccurs == 1) {
  11957. if (wild->any == 1) {
  11958. /*
  11959. * We need to add both transitions:
  11960. *
  11961. * 1. the {"*", "*"} for elements in a namespace.
  11962. */
  11963. pctxt->state =
  11964. xmlAutomataNewTransition2(pctxt->am,
  11965. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  11966. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11967. /*
  11968. * 2. the {"*"} for elements in no namespace.
  11969. */
  11970. pctxt->state =
  11971. xmlAutomataNewTransition2(pctxt->am,
  11972. start, NULL, BAD_CAST "*", NULL, wild);
  11973. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11974. } else if (wild->nsSet != NULL) {
  11975. ns = wild->nsSet;
  11976. do {
  11977. pctxt->state = start;
  11978. pctxt->state = xmlAutomataNewTransition2(pctxt->am,
  11979. pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
  11980. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  11981. ns = ns->next;
  11982. } while (ns != NULL);
  11983. } else if (wild->negNsSet != NULL) {
  11984. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  11985. start, end, BAD_CAST "*", wild->negNsSet->value,
  11986. wild);
  11987. }
  11988. } else {
  11989. int counter;
  11990. xmlAutomataStatePtr hop;
  11991. int maxOccurs =
  11992. particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
  11993. particle->maxOccurs - 1;
  11994. int minOccurs =
  11995. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11996. counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  11997. hop = xmlAutomataNewState(pctxt->am);
  11998. if (wild->any == 1) {
  11999. pctxt->state =
  12000. xmlAutomataNewTransition2(pctxt->am,
  12001. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12002. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12003. pctxt->state =
  12004. xmlAutomataNewTransition2(pctxt->am,
  12005. start, NULL, BAD_CAST "*", NULL, wild);
  12006. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12007. } else if (wild->nsSet != NULL) {
  12008. ns = wild->nsSet;
  12009. do {
  12010. pctxt->state =
  12011. xmlAutomataNewTransition2(pctxt->am,
  12012. start, NULL, BAD_CAST "*", ns->value, wild);
  12013. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12014. ns = ns->next;
  12015. } while (ns != NULL);
  12016. } else if (wild->negNsSet != NULL) {
  12017. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12018. start, hop, BAD_CAST "*", wild->negNsSet->value,
  12019. wild);
  12020. }
  12021. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  12022. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12023. }
  12024. if (particle->minOccurs == 0) {
  12025. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12026. ret = 1;
  12027. }
  12028. pctxt->state = end;
  12029. break;
  12030. }
  12031. case XML_SCHEMA_TYPE_ELEMENT:
  12032. ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
  12033. break;
  12034. case XML_SCHEMA_TYPE_SEQUENCE:{
  12035. xmlSchemaTreeItemPtr sub;
  12036. ret = 1;
  12037. /*
  12038. * If max and min occurances are default (1) then
  12039. * simply iterate over the particles of the <sequence>.
  12040. */
  12041. if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
  12042. sub = particle->children->children;
  12043. while (sub != NULL) {
  12044. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12045. (xmlSchemaParticlePtr) sub);
  12046. if (tmp2 != 1) ret = 0;
  12047. sub = sub->next;
  12048. }
  12049. } else {
  12050. xmlAutomataStatePtr oldstate = pctxt->state;
  12051. if (particle->maxOccurs >= UNBOUNDED) {
  12052. if (particle->minOccurs > 1) {
  12053. xmlAutomataStatePtr tmp;
  12054. int counter;
  12055. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12056. oldstate, NULL);
  12057. oldstate = pctxt->state;
  12058. counter = xmlAutomataNewCounter(pctxt->am,
  12059. particle->minOccurs - 1, UNBOUNDED);
  12060. sub = particle->children->children;
  12061. while (sub != NULL) {
  12062. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12063. (xmlSchemaParticlePtr) sub);
  12064. if (tmp2 != 1) ret = 0;
  12065. sub = sub->next;
  12066. }
  12067. tmp = pctxt->state;
  12068. xmlAutomataNewCountedTrans(pctxt->am, tmp,
  12069. oldstate, counter);
  12070. pctxt->state =
  12071. xmlAutomataNewCounterTrans(pctxt->am, tmp,
  12072. NULL, counter);
  12073. if (ret == 1)
  12074. xmlAutomataNewEpsilon(pctxt->am,
  12075. oldstate, pctxt->state);
  12076. } else {
  12077. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12078. oldstate, NULL);
  12079. oldstate = pctxt->state;
  12080. sub = particle->children->children;
  12081. while (sub != NULL) {
  12082. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12083. (xmlSchemaParticlePtr) sub);
  12084. if (tmp2 != 1) ret = 0;
  12085. sub = sub->next;
  12086. }
  12087. xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
  12088. oldstate);
  12089. /*
  12090. * epsilon needed to block previous trans from
  12091. * being allowed to enter back from another
  12092. * construct
  12093. */
  12094. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12095. pctxt->state, NULL);
  12096. if (particle->minOccurs == 0) {
  12097. xmlAutomataNewEpsilon(pctxt->am,
  12098. oldstate, pctxt->state);
  12099. ret = 1;
  12100. }
  12101. }
  12102. } else if ((particle->maxOccurs > 1)
  12103. || (particle->minOccurs > 1)) {
  12104. xmlAutomataStatePtr tmp;
  12105. int counter;
  12106. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12107. oldstate, NULL);
  12108. oldstate = pctxt->state;
  12109. counter = xmlAutomataNewCounter(pctxt->am,
  12110. particle->minOccurs - 1,
  12111. particle->maxOccurs - 1);
  12112. sub = particle->children->children;
  12113. while (sub != NULL) {
  12114. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12115. (xmlSchemaParticlePtr) sub);
  12116. if (tmp2 != 1) ret = 0;
  12117. sub = sub->next;
  12118. }
  12119. tmp = pctxt->state;
  12120. xmlAutomataNewCountedTrans(pctxt->am,
  12121. tmp, oldstate, counter);
  12122. pctxt->state =
  12123. xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
  12124. counter);
  12125. if ((particle->minOccurs == 0) || (ret == 1)) {
  12126. xmlAutomataNewEpsilon(pctxt->am,
  12127. oldstate, pctxt->state);
  12128. ret = 1;
  12129. }
  12130. } else {
  12131. sub = particle->children->children;
  12132. while (sub != NULL) {
  12133. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12134. (xmlSchemaParticlePtr) sub);
  12135. if (tmp2 != 1) ret = 0;
  12136. sub = sub->next;
  12137. }
  12138. if (particle->minOccurs == 0) {
  12139. xmlAutomataNewEpsilon(pctxt->am, oldstate,
  12140. pctxt->state);
  12141. ret = 1;
  12142. }
  12143. }
  12144. }
  12145. break;
  12146. }
  12147. case XML_SCHEMA_TYPE_CHOICE:{
  12148. xmlSchemaTreeItemPtr sub;
  12149. xmlAutomataStatePtr start, end;
  12150. ret = 0;
  12151. start = pctxt->state;
  12152. end = xmlAutomataNewState(pctxt->am);
  12153. /*
  12154. * iterate over the subtypes and remerge the end with an
  12155. * epsilon transition
  12156. */
  12157. if (particle->maxOccurs == 1) {
  12158. sub = particle->children->children;
  12159. while (sub != NULL) {
  12160. pctxt->state = start;
  12161. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12162. (xmlSchemaParticlePtr) sub);
  12163. if (tmp2 == 1) ret = 1;
  12164. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12165. sub = sub->next;
  12166. }
  12167. } else {
  12168. int counter;
  12169. xmlAutomataStatePtr hop, base;
  12170. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12171. UNBOUNDED : particle->maxOccurs - 1;
  12172. int minOccurs =
  12173. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12174. /*
  12175. * use a counter to keep track of the number of transtions
  12176. * which went through the choice.
  12177. */
  12178. counter =
  12179. xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12180. hop = xmlAutomataNewState(pctxt->am);
  12181. base = xmlAutomataNewState(pctxt->am);
  12182. sub = particle->children->children;
  12183. while (sub != NULL) {
  12184. pctxt->state = base;
  12185. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12186. (xmlSchemaParticlePtr) sub);
  12187. if (tmp2 == 1) ret = 1;
  12188. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12189. sub = sub->next;
  12190. }
  12191. xmlAutomataNewEpsilon(pctxt->am, start, base);
  12192. xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
  12193. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12194. if (ret == 1)
  12195. xmlAutomataNewEpsilon(pctxt->am, base, end);
  12196. }
  12197. if (particle->minOccurs == 0) {
  12198. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12199. ret = 1;
  12200. }
  12201. pctxt->state = end;
  12202. break;
  12203. }
  12204. case XML_SCHEMA_TYPE_ALL:{
  12205. xmlAutomataStatePtr start, tmp;
  12206. xmlSchemaParticlePtr sub;
  12207. xmlSchemaElementPtr elemDecl;
  12208. ret = 1;
  12209. sub = (xmlSchemaParticlePtr) particle->children->children;
  12210. if (sub == NULL)
  12211. break;
  12212. ret = 0;
  12213. start = pctxt->state;
  12214. tmp = xmlAutomataNewState(pctxt->am);
  12215. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
  12216. pctxt->state = tmp;
  12217. while (sub != NULL) {
  12218. pctxt->state = tmp;
  12219. elemDecl = (xmlSchemaElementPtr) sub->children;
  12220. if (elemDecl == NULL) {
  12221. PERROR_INT("xmlSchemaBuildAContentModel",
  12222. "<element> particle has no term");
  12223. return(ret);
  12224. };
  12225. /*
  12226. * NOTE: The {max occurs} of all the particles in the
  12227. * {particles} of the group must be 0 or 1; this is
  12228. * already ensured during the parse of the content of
  12229. * <all>.
  12230. */
  12231. if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  12232. int counter;
  12233. /*
  12234. * This is an abstract group, we need to share
  12235. * the same counter for all the element transitions
  12236. * derived from the group
  12237. */
  12238. counter = xmlAutomataNewCounter(pctxt->am,
  12239. sub->minOccurs, sub->maxOccurs);
  12240. xmlSchemaBuildContentModelForSubstGroup(pctxt,
  12241. sub, counter, pctxt->state);
  12242. } else {
  12243. if ((sub->minOccurs == 1) &&
  12244. (sub->maxOccurs == 1)) {
  12245. xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
  12246. pctxt->state,
  12247. elemDecl->name,
  12248. elemDecl->targetNamespace,
  12249. 1, 1, elemDecl);
  12250. } else if ((sub->minOccurs == 0) &&
  12251. (sub->maxOccurs == 1)) {
  12252. xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
  12253. pctxt->state,
  12254. elemDecl->name,
  12255. elemDecl->targetNamespace,
  12256. 0,
  12257. 1,
  12258. elemDecl);
  12259. }
  12260. }
  12261. sub = (xmlSchemaParticlePtr) sub->next;
  12262. }
  12263. pctxt->state =
  12264. xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
  12265. if (particle->minOccurs == 0) {
  12266. xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
  12267. ret = 1;
  12268. }
  12269. break;
  12270. }
  12271. case XML_SCHEMA_TYPE_GROUP:
  12272. /*
  12273. * If we hit a model group definition, then this means that
  12274. * it was empty, thus was not substituted for the containing
  12275. * model group. Just do nothing in this case.
  12276. * TODO: But the group should be substituted and not occur at
  12277. * all in the content model at this point. Fix this.
  12278. */
  12279. ret = 1;
  12280. break;
  12281. default:
  12282. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  12283. "xmlSchemaBuildAContentModel",
  12284. "found unexpected term of type '%s' in content model",
  12285. WXS_ITEM_TYPE_NAME(particle->children), NULL);
  12286. return(ret);
  12287. }
  12288. return(ret);
  12289. }
  12290. /**
  12291. * xmlSchemaBuildContentModel:
  12292. * @ctxt: the schema parser context
  12293. * @type: the complex type definition
  12294. * @name: the element name
  12295. *
  12296. * Builds the content model of the complex type.
  12297. */
  12298. static void
  12299. xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
  12300. xmlSchemaParserCtxtPtr ctxt)
  12301. {
  12302. if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
  12303. (type->contModel != NULL) ||
  12304. ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
  12305. (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
  12306. return;
  12307. #ifdef DEBUG_CONTENT
  12308. xmlGenericError(xmlGenericErrorContext,
  12309. "Building content model for %s\n", name);
  12310. #endif
  12311. ctxt->am = NULL;
  12312. ctxt->am = xmlNewAutomata();
  12313. if (ctxt->am == NULL) {
  12314. xmlGenericError(xmlGenericErrorContext,
  12315. "Cannot create automata for complex type %s\n", type->name);
  12316. return;
  12317. }
  12318. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  12319. /*
  12320. * Build the automaton.
  12321. */
  12322. xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
  12323. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  12324. type->contModel = xmlAutomataCompile(ctxt->am);
  12325. if (type->contModel == NULL) {
  12326. xmlSchemaPCustomErr(ctxt,
  12327. XML_SCHEMAP_INTERNAL,
  12328. WXS_BASIC_CAST type, type->node,
  12329. "Failed to compile the content model", NULL);
  12330. } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
  12331. xmlSchemaPCustomErr(ctxt,
  12332. XML_SCHEMAP_NOT_DETERMINISTIC,
  12333. /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
  12334. WXS_BASIC_CAST type, type->node,
  12335. "The content model is not determinist", NULL);
  12336. } else {
  12337. #ifdef DEBUG_CONTENT_REGEXP
  12338. xmlGenericError(xmlGenericErrorContext,
  12339. "Content model of %s:\n", type->name);
  12340. xmlRegexpPrint(stderr, type->contModel);
  12341. #endif
  12342. }
  12343. ctxt->state = NULL;
  12344. xmlFreeAutomata(ctxt->am);
  12345. ctxt->am = NULL;
  12346. }
  12347. /**
  12348. * xmlSchemaResolveElementReferences:
  12349. * @elem: the schema element context
  12350. * @ctxt: the schema parser context
  12351. *
  12352. * Resolves the references of an element declaration
  12353. * or particle, which has an element declaration as it's
  12354. * term.
  12355. */
  12356. static void
  12357. xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
  12358. xmlSchemaParserCtxtPtr ctxt)
  12359. {
  12360. if ((ctxt == NULL) || (elemDecl == NULL) ||
  12361. ((elemDecl != NULL) &&
  12362. (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
  12363. return;
  12364. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
  12365. if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
  12366. xmlSchemaTypePtr type;
  12367. /* (type definition) ... otherwise the type definition �resolved�
  12368. * to by the �actual value� of the type [attribute] ...
  12369. */
  12370. type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
  12371. elemDecl->namedTypeNs);
  12372. if (type == NULL) {
  12373. xmlSchemaPResCompAttrErr(ctxt,
  12374. XML_SCHEMAP_SRC_RESOLVE,
  12375. WXS_BASIC_CAST elemDecl, elemDecl->node,
  12376. "type", elemDecl->namedType, elemDecl->namedTypeNs,
  12377. XML_SCHEMA_TYPE_BASIC, "type definition");
  12378. } else
  12379. elemDecl->subtypes = type;
  12380. }
  12381. if (elemDecl->substGroup != NULL) {
  12382. xmlSchemaElementPtr substHead;
  12383. /*
  12384. * FIXME TODO: Do we need a new field in _xmlSchemaElement for
  12385. * substitutionGroup?
  12386. */
  12387. substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
  12388. elemDecl->substGroupNs);
  12389. if (substHead == NULL) {
  12390. xmlSchemaPResCompAttrErr(ctxt,
  12391. XML_SCHEMAP_SRC_RESOLVE,
  12392. WXS_BASIC_CAST elemDecl, NULL,
  12393. "substitutionGroup", elemDecl->substGroup,
  12394. elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
  12395. } else {
  12396. xmlSchemaResolveElementReferences(substHead, ctxt);
  12397. /*
  12398. * Set the "substitution group affiliation".
  12399. * NOTE that now we use the "refDecl" field for this.
  12400. */
  12401. WXS_SUBST_HEAD(elemDecl) = substHead;
  12402. /*
  12403. * The type definitions is set to:
  12404. * SPEC "...the {type definition} of the element
  12405. * declaration �resolved� to by the �actual value�
  12406. * of the substitutionGroup [attribute], if present"
  12407. */
  12408. if (elemDecl->subtypes == NULL)
  12409. elemDecl->subtypes = substHead->subtypes;
  12410. }
  12411. }
  12412. /*
  12413. * SPEC "The definition of anyType serves as the default type definition
  12414. * for element declarations whose XML representation does not specify one."
  12415. */
  12416. if ((elemDecl->subtypes == NULL) &&
  12417. (elemDecl->namedType == NULL) &&
  12418. (elemDecl->substGroup == NULL))
  12419. elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  12420. }
  12421. /**
  12422. * xmlSchemaResolveUnionMemberTypes:
  12423. * @ctxt: the schema parser context
  12424. * @type: the schema simple type definition
  12425. *
  12426. * Checks and builds the "member type definitions" property of the union
  12427. * simple type. This handles part (1), part (2) is done in
  12428. * xmlSchemaFinishMemberTypeDefinitionsProperty()
  12429. *
  12430. * Returns -1 in case of an internal error, 0 otherwise.
  12431. */
  12432. static int
  12433. xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
  12434. xmlSchemaTypePtr type)
  12435. {
  12436. xmlSchemaTypeLinkPtr link, lastLink, newLink;
  12437. xmlSchemaTypePtr memberType;
  12438. /*
  12439. * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
  12440. * define the explicit members as the type definitions �resolved�
  12441. * to by the items in the �actual value� of the memberTypes [attribute],
  12442. * if any, followed by the type definitions corresponding to the
  12443. * <simpleType>s among the [children] of <union>, if any."
  12444. */
  12445. /*
  12446. * Resolve references.
  12447. */
  12448. link = type->memberTypes;
  12449. lastLink = NULL;
  12450. while (link != NULL) {
  12451. const xmlChar *name, *nsName;
  12452. name = ((xmlSchemaQNameRefPtr) link->type)->name;
  12453. nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
  12454. memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
  12455. if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
  12456. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  12457. WXS_BASIC_CAST type, type->node, "memberTypes",
  12458. name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
  12459. /*
  12460. * Remove the member type link.
  12461. */
  12462. if (lastLink == NULL)
  12463. type->memberTypes = link->next;
  12464. else
  12465. lastLink->next = link->next;
  12466. newLink = link;
  12467. link = link->next;
  12468. xmlFree(newLink);
  12469. } else {
  12470. link->type = memberType;
  12471. lastLink = link;
  12472. link = link->next;
  12473. }
  12474. }
  12475. /*
  12476. * Add local simple types,
  12477. */
  12478. memberType = type->subtypes;
  12479. while (memberType != NULL) {
  12480. link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
  12481. if (link == NULL) {
  12482. xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
  12483. return (-1);
  12484. }
  12485. link->type = memberType;
  12486. link->next = NULL;
  12487. if (lastLink == NULL)
  12488. type->memberTypes = link;
  12489. else
  12490. lastLink->next = link;
  12491. lastLink = link;
  12492. memberType = memberType->next;
  12493. }
  12494. return (0);
  12495. }
  12496. /**
  12497. * xmlSchemaIsDerivedFromBuiltInType:
  12498. * @ctxt: the schema parser context
  12499. * @type: the type definition
  12500. * @valType: the value type
  12501. *
  12502. *
  12503. * Returns 1 if the type has the given value type, or
  12504. * is derived from such a type.
  12505. */
  12506. static int
  12507. xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12508. {
  12509. if (type == NULL)
  12510. return (0);
  12511. if (WXS_IS_COMPLEX(type))
  12512. return (0);
  12513. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12514. if (type->builtInType == valType)
  12515. return(1);
  12516. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12517. (type->builtInType == XML_SCHEMAS_ANYTYPE))
  12518. return (0);
  12519. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12520. }
  12521. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12522. }
  12523. #if 0
  12524. /**
  12525. * xmlSchemaIsDerivedFromBuiltInType:
  12526. * @ctxt: the schema parser context
  12527. * @type: the type definition
  12528. * @valType: the value type
  12529. *
  12530. *
  12531. * Returns 1 if the type has the given value type, or
  12532. * is derived from such a type.
  12533. */
  12534. static int
  12535. xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12536. {
  12537. if (type == NULL)
  12538. return (0);
  12539. if (WXS_IS_COMPLEX(type))
  12540. return (0);
  12541. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12542. if (type->builtInType == valType)
  12543. return(1);
  12544. return (0);
  12545. } else
  12546. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12547. return (0);
  12548. }
  12549. static xmlSchemaTypePtr
  12550. xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
  12551. {
  12552. if (type == NULL)
  12553. return (NULL);
  12554. if (WXS_IS_COMPLEX(type))
  12555. return (NULL);
  12556. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12557. return(type);
  12558. return(xmlSchemaQueryBuiltInType(type->subtypes));
  12559. }
  12560. #endif
  12561. /**
  12562. * xmlSchemaGetPrimitiveType:
  12563. * @type: the simpleType definition
  12564. *
  12565. * Returns the primitive type of the given type or
  12566. * NULL in case of error.
  12567. */
  12568. static xmlSchemaTypePtr
  12569. xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
  12570. {
  12571. while (type != NULL) {
  12572. /*
  12573. * Note that anySimpleType is actually not a primitive type
  12574. * but we need that here.
  12575. */
  12576. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12577. (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
  12578. return (type);
  12579. type = type->baseType;
  12580. }
  12581. return (NULL);
  12582. }
  12583. #if 0
  12584. /**
  12585. * xmlSchemaGetBuiltInTypeAncestor:
  12586. * @type: the simpleType definition
  12587. *
  12588. * Returns the primitive type of the given type or
  12589. * NULL in case of error.
  12590. */
  12591. static xmlSchemaTypePtr
  12592. xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
  12593. {
  12594. if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
  12595. return (0);
  12596. while (type != NULL) {
  12597. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12598. return (type);
  12599. type = type->baseType;
  12600. }
  12601. return (NULL);
  12602. }
  12603. #endif
  12604. /**
  12605. * xmlSchemaCloneWildcardNsConstraints:
  12606. * @ctxt: the schema parser context
  12607. * @dest: the destination wildcard
  12608. * @source: the source wildcard
  12609. *
  12610. * Clones the namespace constraints of source
  12611. * and assignes them to dest.
  12612. * Returns -1 on internal error, 0 otherwise.
  12613. */
  12614. static int
  12615. xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
  12616. xmlSchemaWildcardPtr dest,
  12617. xmlSchemaWildcardPtr source)
  12618. {
  12619. xmlSchemaWildcardNsPtr cur, tmp, last;
  12620. if ((source == NULL) || (dest == NULL))
  12621. return(-1);
  12622. dest->any = source->any;
  12623. cur = source->nsSet;
  12624. last = NULL;
  12625. while (cur != NULL) {
  12626. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12627. if (tmp == NULL)
  12628. return(-1);
  12629. tmp->value = cur->value;
  12630. if (last == NULL)
  12631. dest->nsSet = tmp;
  12632. else
  12633. last->next = tmp;
  12634. last = tmp;
  12635. cur = cur->next;
  12636. }
  12637. if (dest->negNsSet != NULL)
  12638. xmlSchemaFreeWildcardNsSet(dest->negNsSet);
  12639. if (source->negNsSet != NULL) {
  12640. dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12641. if (dest->negNsSet == NULL)
  12642. return(-1);
  12643. dest->negNsSet->value = source->negNsSet->value;
  12644. } else
  12645. dest->negNsSet = NULL;
  12646. return(0);
  12647. }
  12648. /**
  12649. * xmlSchemaUnionWildcards:
  12650. * @ctxt: the schema parser context
  12651. * @completeWild: the first wildcard
  12652. * @curWild: the second wildcard
  12653. *
  12654. * Unions the namespace constraints of the given wildcards.
  12655. * @completeWild will hold the resulting union.
  12656. * Returns a positive error code on failure, -1 in case of an
  12657. * internal error, 0 otherwise.
  12658. */
  12659. static int
  12660. xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
  12661. xmlSchemaWildcardPtr completeWild,
  12662. xmlSchemaWildcardPtr curWild)
  12663. {
  12664. xmlSchemaWildcardNsPtr cur, curB, tmp;
  12665. /*
  12666. * 1 If O1 and O2 are the same value, then that value must be the
  12667. * value.
  12668. */
  12669. if ((completeWild->any == curWild->any) &&
  12670. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12671. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12672. if ((completeWild->negNsSet == NULL) ||
  12673. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12674. if (completeWild->nsSet != NULL) {
  12675. int found = 0;
  12676. /*
  12677. * Check equality of sets.
  12678. */
  12679. cur = completeWild->nsSet;
  12680. while (cur != NULL) {
  12681. found = 0;
  12682. curB = curWild->nsSet;
  12683. while (curB != NULL) {
  12684. if (cur->value == curB->value) {
  12685. found = 1;
  12686. break;
  12687. }
  12688. curB = curB->next;
  12689. }
  12690. if (!found)
  12691. break;
  12692. cur = cur->next;
  12693. }
  12694. if (found)
  12695. return(0);
  12696. } else
  12697. return(0);
  12698. }
  12699. }
  12700. /*
  12701. * 2 If either O1 or O2 is any, then any must be the value
  12702. */
  12703. if (completeWild->any != curWild->any) {
  12704. if (completeWild->any == 0) {
  12705. completeWild->any = 1;
  12706. if (completeWild->nsSet != NULL) {
  12707. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12708. completeWild->nsSet = NULL;
  12709. }
  12710. if (completeWild->negNsSet != NULL) {
  12711. xmlFree(completeWild->negNsSet);
  12712. completeWild->negNsSet = NULL;
  12713. }
  12714. }
  12715. return (0);
  12716. }
  12717. /*
  12718. * 3 If both O1 and O2 are sets of (namespace names or �absent�),
  12719. * then the union of those sets must be the value.
  12720. */
  12721. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12722. int found;
  12723. xmlSchemaWildcardNsPtr start;
  12724. cur = curWild->nsSet;
  12725. start = completeWild->nsSet;
  12726. while (cur != NULL) {
  12727. found = 0;
  12728. curB = start;
  12729. while (curB != NULL) {
  12730. if (cur->value == curB->value) {
  12731. found = 1;
  12732. break;
  12733. }
  12734. curB = curB->next;
  12735. }
  12736. if (!found) {
  12737. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12738. if (tmp == NULL)
  12739. return (-1);
  12740. tmp->value = cur->value;
  12741. tmp->next = completeWild->nsSet;
  12742. completeWild->nsSet = tmp;
  12743. }
  12744. cur = cur->next;
  12745. }
  12746. return(0);
  12747. }
  12748. /*
  12749. * 4 If the two are negations of different values (namespace names
  12750. * or �absent�), then a pair of not and �absent� must be the value.
  12751. */
  12752. if ((completeWild->negNsSet != NULL) &&
  12753. (curWild->negNsSet != NULL) &&
  12754. (completeWild->negNsSet->value != curWild->negNsSet->value)) {
  12755. completeWild->negNsSet->value = NULL;
  12756. return(0);
  12757. }
  12758. /*
  12759. * 5.
  12760. */
  12761. if (((completeWild->negNsSet != NULL) &&
  12762. (completeWild->negNsSet->value != NULL) &&
  12763. (curWild->nsSet != NULL)) ||
  12764. ((curWild->negNsSet != NULL) &&
  12765. (curWild->negNsSet->value != NULL) &&
  12766. (completeWild->nsSet != NULL))) {
  12767. int nsFound, absentFound = 0;
  12768. if (completeWild->nsSet != NULL) {
  12769. cur = completeWild->nsSet;
  12770. curB = curWild->negNsSet;
  12771. } else {
  12772. cur = curWild->nsSet;
  12773. curB = completeWild->negNsSet;
  12774. }
  12775. nsFound = 0;
  12776. while (cur != NULL) {
  12777. if (cur->value == NULL)
  12778. absentFound = 1;
  12779. else if (cur->value == curB->value)
  12780. nsFound = 1;
  12781. if (nsFound && absentFound)
  12782. break;
  12783. cur = cur->next;
  12784. }
  12785. if (nsFound && absentFound) {
  12786. /*
  12787. * 5.1 If the set S includes both the negated namespace
  12788. * name and �absent�, then any must be the value.
  12789. */
  12790. completeWild->any = 1;
  12791. if (completeWild->nsSet != NULL) {
  12792. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12793. completeWild->nsSet = NULL;
  12794. }
  12795. if (completeWild->negNsSet != NULL) {
  12796. xmlFree(completeWild->negNsSet);
  12797. completeWild->negNsSet = NULL;
  12798. }
  12799. } else if (nsFound && (!absentFound)) {
  12800. /*
  12801. * 5.2 If the set S includes the negated namespace name
  12802. * but not �absent�, then a pair of not and �absent� must
  12803. * be the value.
  12804. */
  12805. if (completeWild->nsSet != NULL) {
  12806. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12807. completeWild->nsSet = NULL;
  12808. }
  12809. if (completeWild->negNsSet == NULL) {
  12810. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12811. if (completeWild->negNsSet == NULL)
  12812. return (-1);
  12813. }
  12814. completeWild->negNsSet->value = NULL;
  12815. } else if ((!nsFound) && absentFound) {
  12816. /*
  12817. * 5.3 If the set S includes �absent� but not the negated
  12818. * namespace name, then the union is not expressible.
  12819. */
  12820. xmlSchemaPErr(ctxt, completeWild->node,
  12821. XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
  12822. "The union of the wilcard is not expressible.\n",
  12823. NULL, NULL);
  12824. return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
  12825. } else if ((!nsFound) && (!absentFound)) {
  12826. /*
  12827. * 5.4 If the set S does not include either the negated namespace
  12828. * name or �absent�, then whichever of O1 or O2 is a pair of not
  12829. * and a namespace name must be the value.
  12830. */
  12831. if (completeWild->negNsSet == NULL) {
  12832. if (completeWild->nsSet != NULL) {
  12833. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12834. completeWild->nsSet = NULL;
  12835. }
  12836. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12837. if (completeWild->negNsSet == NULL)
  12838. return (-1);
  12839. completeWild->negNsSet->value = curWild->negNsSet->value;
  12840. }
  12841. }
  12842. return (0);
  12843. }
  12844. /*
  12845. * 6.
  12846. */
  12847. if (((completeWild->negNsSet != NULL) &&
  12848. (completeWild->negNsSet->value == NULL) &&
  12849. (curWild->nsSet != NULL)) ||
  12850. ((curWild->negNsSet != NULL) &&
  12851. (curWild->negNsSet->value == NULL) &&
  12852. (completeWild->nsSet != NULL))) {
  12853. if (completeWild->nsSet != NULL) {
  12854. cur = completeWild->nsSet;
  12855. } else {
  12856. cur = curWild->nsSet;
  12857. }
  12858. while (cur != NULL) {
  12859. if (cur->value == NULL) {
  12860. /*
  12861. * 6.1 If the set S includes �absent�, then any must be the
  12862. * value.
  12863. */
  12864. completeWild->any = 1;
  12865. if (completeWild->nsSet != NULL) {
  12866. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12867. completeWild->nsSet = NULL;
  12868. }
  12869. if (completeWild->negNsSet != NULL) {
  12870. xmlFree(completeWild->negNsSet);
  12871. completeWild->negNsSet = NULL;
  12872. }
  12873. return (0);
  12874. }
  12875. cur = cur->next;
  12876. }
  12877. if (completeWild->negNsSet == NULL) {
  12878. /*
  12879. * 6.2 If the set S does not include �absent�, then a pair of not
  12880. * and �absent� must be the value.
  12881. */
  12882. if (completeWild->nsSet != NULL) {
  12883. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12884. completeWild->nsSet = NULL;
  12885. }
  12886. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12887. if (completeWild->negNsSet == NULL)
  12888. return (-1);
  12889. completeWild->negNsSet->value = NULL;
  12890. }
  12891. return (0);
  12892. }
  12893. return (0);
  12894. }
  12895. /**
  12896. * xmlSchemaIntersectWildcards:
  12897. * @ctxt: the schema parser context
  12898. * @completeWild: the first wildcard
  12899. * @curWild: the second wildcard
  12900. *
  12901. * Intersects the namespace constraints of the given wildcards.
  12902. * @completeWild will hold the resulting intersection.
  12903. * Returns a positive error code on failure, -1 in case of an
  12904. * internal error, 0 otherwise.
  12905. */
  12906. static int
  12907. xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
  12908. xmlSchemaWildcardPtr completeWild,
  12909. xmlSchemaWildcardPtr curWild)
  12910. {
  12911. xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
  12912. /*
  12913. * 1 If O1 and O2 are the same value, then that value must be the
  12914. * value.
  12915. */
  12916. if ((completeWild->any == curWild->any) &&
  12917. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12918. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12919. if ((completeWild->negNsSet == NULL) ||
  12920. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12921. if (completeWild->nsSet != NULL) {
  12922. int found = 0;
  12923. /*
  12924. * Check equality of sets.
  12925. */
  12926. cur = completeWild->nsSet;
  12927. while (cur != NULL) {
  12928. found = 0;
  12929. curB = curWild->nsSet;
  12930. while (curB != NULL) {
  12931. if (cur->value == curB->value) {
  12932. found = 1;
  12933. break;
  12934. }
  12935. curB = curB->next;
  12936. }
  12937. if (!found)
  12938. break;
  12939. cur = cur->next;
  12940. }
  12941. if (found)
  12942. return(0);
  12943. } else
  12944. return(0);
  12945. }
  12946. }
  12947. /*
  12948. * 2 If either O1 or O2 is any, then the other must be the value.
  12949. */
  12950. if ((completeWild->any != curWild->any) && (completeWild->any)) {
  12951. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  12952. return(-1);
  12953. return(0);
  12954. }
  12955. /*
  12956. * 3 If either O1 or O2 is a pair of not and a value (a namespace
  12957. * name or �absent�) and the other is a set of (namespace names or
  12958. * �absent�), then that set, minus the negated value if it was in
  12959. * the set, minus �absent� if it was in the set, must be the value.
  12960. */
  12961. if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
  12962. ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
  12963. const xmlChar *neg;
  12964. if (completeWild->nsSet == NULL) {
  12965. neg = completeWild->negNsSet->value;
  12966. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  12967. return(-1);
  12968. } else
  12969. neg = curWild->negNsSet->value;
  12970. /*
  12971. * Remove absent and negated.
  12972. */
  12973. prev = NULL;
  12974. cur = completeWild->nsSet;
  12975. while (cur != NULL) {
  12976. if (cur->value == NULL) {
  12977. if (prev == NULL)
  12978. completeWild->nsSet = cur->next;
  12979. else
  12980. prev->next = cur->next;
  12981. xmlFree(cur);
  12982. break;
  12983. }
  12984. prev = cur;
  12985. cur = cur->next;
  12986. }
  12987. if (neg != NULL) {
  12988. prev = NULL;
  12989. cur = completeWild->nsSet;
  12990. while (cur != NULL) {
  12991. if (cur->value == neg) {
  12992. if (prev == NULL)
  12993. completeWild->nsSet = cur->next;
  12994. else
  12995. prev->next = cur->next;
  12996. xmlFree(cur);
  12997. break;
  12998. }
  12999. prev = cur;
  13000. cur = cur->next;
  13001. }
  13002. }
  13003. return(0);
  13004. }
  13005. /*
  13006. * 4 If both O1 and O2 are sets of (namespace names or �absent�),
  13007. * then the intersection of those sets must be the value.
  13008. */
  13009. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  13010. int found;
  13011. cur = completeWild->nsSet;
  13012. prev = NULL;
  13013. while (cur != NULL) {
  13014. found = 0;
  13015. curB = curWild->nsSet;
  13016. while (curB != NULL) {
  13017. if (cur->value == curB->value) {
  13018. found = 1;
  13019. break;
  13020. }
  13021. curB = curB->next;
  13022. }
  13023. if (!found) {
  13024. if (prev == NULL)
  13025. completeWild->nsSet = cur->next;
  13026. else
  13027. prev->next = cur->next;
  13028. tmp = cur->next;
  13029. xmlFree(cur);
  13030. cur = tmp;
  13031. continue;
  13032. }
  13033. prev = cur;
  13034. cur = cur->next;
  13035. }
  13036. return(0);
  13037. }
  13038. /* 5 If the two are negations of different namespace names,
  13039. * then the intersection is not expressible
  13040. */
  13041. if ((completeWild->negNsSet != NULL) &&
  13042. (curWild->negNsSet != NULL) &&
  13043. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13044. (completeWild->negNsSet->value != NULL) &&
  13045. (curWild->negNsSet->value != NULL)) {
  13046. xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
  13047. "The intersection of the wilcard is not expressible.\n",
  13048. NULL, NULL);
  13049. return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
  13050. }
  13051. /*
  13052. * 6 If the one is a negation of a namespace name and the other
  13053. * is a negation of �absent�, then the one which is the negation
  13054. * of a namespace name must be the value.
  13055. */
  13056. if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
  13057. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13058. (completeWild->negNsSet->value == NULL)) {
  13059. completeWild->negNsSet->value = curWild->negNsSet->value;
  13060. }
  13061. return(0);
  13062. }
  13063. /**
  13064. * xmlSchemaIsWildcardNsConstraintSubset:
  13065. * @ctxt: the schema parser context
  13066. * @sub: the first wildcard
  13067. * @super: the second wildcard
  13068. *
  13069. * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
  13070. *
  13071. * Returns 0 if the namespace constraint of @sub is an intensional
  13072. * subset of @super, 1 otherwise.
  13073. */
  13074. static int
  13075. xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
  13076. xmlSchemaWildcardPtr super)
  13077. {
  13078. /*
  13079. * 1 super must be any.
  13080. */
  13081. if (super->any)
  13082. return (0);
  13083. /*
  13084. * 2.1 sub must be a pair of not and a namespace name or �absent�.
  13085. * 2.2 super must be a pair of not and the same value.
  13086. */
  13087. if ((sub->negNsSet != NULL) &&
  13088. (super->negNsSet != NULL) &&
  13089. (sub->negNsSet->value == sub->negNsSet->value))
  13090. return (0);
  13091. /*
  13092. * 3.1 sub must be a set whose members are either namespace names or �absent�.
  13093. */
  13094. if (sub->nsSet != NULL) {
  13095. /*
  13096. * 3.2.1 super must be the same set or a superset thereof.
  13097. */
  13098. if (super->nsSet != NULL) {
  13099. xmlSchemaWildcardNsPtr cur, curB;
  13100. int found = 0;
  13101. cur = sub->nsSet;
  13102. while (cur != NULL) {
  13103. found = 0;
  13104. curB = super->nsSet;
  13105. while (curB != NULL) {
  13106. if (cur->value == curB->value) {
  13107. found = 1;
  13108. break;
  13109. }
  13110. curB = curB->next;
  13111. }
  13112. if (!found)
  13113. return (1);
  13114. cur = cur->next;
  13115. }
  13116. if (found)
  13117. return (0);
  13118. } else if (super->negNsSet != NULL) {
  13119. xmlSchemaWildcardNsPtr cur;
  13120. /*
  13121. * 3.2.2 super must be a pair of not and a namespace name or
  13122. * �absent� and that value must not be in sub's set.
  13123. */
  13124. cur = sub->nsSet;
  13125. while (cur != NULL) {
  13126. if (cur->value == super->negNsSet->value)
  13127. return (1);
  13128. cur = cur->next;
  13129. }
  13130. return (0);
  13131. }
  13132. }
  13133. return (1);
  13134. }
  13135. static int
  13136. xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
  13137. int *fixed,
  13138. const xmlChar **value,
  13139. xmlSchemaValPtr *val)
  13140. {
  13141. *fixed = 0;
  13142. *value = NULL;
  13143. if (val != 0)
  13144. *val = NULL;
  13145. if (attruse->defValue != NULL) {
  13146. *value = attruse->defValue;
  13147. if (val != NULL)
  13148. *val = attruse->defVal;
  13149. if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
  13150. *fixed = 1;
  13151. return(1);
  13152. } else if ((attruse->attrDecl != NULL) &&
  13153. (attruse->attrDecl->defValue != NULL)) {
  13154. *value = attruse->attrDecl->defValue;
  13155. if (val != NULL)
  13156. *val = attruse->attrDecl->defVal;
  13157. if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
  13158. *fixed = 1;
  13159. return(1);
  13160. }
  13161. return(0);
  13162. }
  13163. /**
  13164. * xmlSchemaCheckCVCWildcardNamespace:
  13165. * @wild: the wildcard
  13166. * @ns: the namespace
  13167. *
  13168. * Validation Rule: Wildcard allows Namespace Name
  13169. * (cvc-wildcard-namespace)
  13170. *
  13171. * Returns 0 if the given namespace matches the wildcard,
  13172. * 1 otherwise and -1 on API errors.
  13173. */
  13174. static int
  13175. xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
  13176. const xmlChar* ns)
  13177. {
  13178. if (wild == NULL)
  13179. return(-1);
  13180. if (wild->any)
  13181. return(0);
  13182. else if (wild->nsSet != NULL) {
  13183. xmlSchemaWildcardNsPtr cur;
  13184. cur = wild->nsSet;
  13185. while (cur != NULL) {
  13186. if (xmlStrEqual(cur->value, ns))
  13187. return(0);
  13188. cur = cur->next;
  13189. }
  13190. } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
  13191. (!xmlStrEqual(wild->negNsSet->value, ns)))
  13192. return(0);
  13193. return(1);
  13194. }
  13195. #define XML_SCHEMA_ACTION_DERIVE 0
  13196. #define XML_SCHEMA_ACTION_REDEFINE 1
  13197. #define WXS_ACTION_STR(a) \
  13198. ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
  13199. /*
  13200. * Schema Component Constraint:
  13201. * Derivation Valid (Restriction, Complex)
  13202. * derivation-ok-restriction (2) - (4)
  13203. *
  13204. * ATTENTION:
  13205. * In XML Schema 1.1 this will be:
  13206. * Validation Rule:
  13207. * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
  13208. *
  13209. */
  13210. static int
  13211. xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
  13212. int action,
  13213. xmlSchemaBasicItemPtr item,
  13214. xmlSchemaBasicItemPtr baseItem,
  13215. xmlSchemaItemListPtr uses,
  13216. xmlSchemaItemListPtr baseUses,
  13217. xmlSchemaWildcardPtr wild,
  13218. xmlSchemaWildcardPtr baseWild)
  13219. {
  13220. xmlSchemaAttributeUsePtr cur = NULL, bcur;
  13221. int i, j, found; /* err = 0; */
  13222. const xmlChar *bEffValue;
  13223. int effFixed;
  13224. if (uses != NULL) {
  13225. for (i = 0; i < uses->nbItems; i++) {
  13226. cur = uses->items[i];
  13227. found = 0;
  13228. if (baseUses == NULL)
  13229. goto not_found;
  13230. for (j = 0; j < baseUses->nbItems; j++) {
  13231. bcur = baseUses->items[j];
  13232. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13233. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13234. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13235. WXS_ATTRUSE_DECL_TNS(bcur)))
  13236. {
  13237. /*
  13238. * (2.1) "If there is an attribute use in the {attribute
  13239. * uses} of the {base type definition} (call this B) whose
  13240. * {attribute declaration} has the same {name} and {target
  13241. * namespace}, then all of the following must be true:"
  13242. */
  13243. found = 1;
  13244. if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  13245. (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
  13246. {
  13247. xmlChar *str = NULL;
  13248. /*
  13249. * (2.1.1) "one of the following must be true:"
  13250. * (2.1.1.1) "B's {required} is false."
  13251. * (2.1.1.2) "R's {required} is true."
  13252. */
  13253. xmlSchemaPAttrUseErr4(pctxt,
  13254. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
  13255. WXS_ITEM_NODE(item), item, cur,
  13256. "The 'optional' attribute use is inconsistent "
  13257. "with the corresponding 'required' attribute use of "
  13258. "the %s %s",
  13259. WXS_ACTION_STR(action),
  13260. xmlSchemaGetComponentDesignation(&str, baseItem),
  13261. NULL, NULL);
  13262. FREE_AND_NULL(str);
  13263. /* err = pctxt->err; */
  13264. } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  13265. WXS_ATTRUSE_TYPEDEF(cur),
  13266. WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
  13267. {
  13268. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  13269. /*
  13270. * SPEC (2.1.2) "R's {attribute declaration}'s
  13271. * {type definition} must be validly derived from
  13272. * B's {type definition} given the empty set as
  13273. * defined in Type Derivation OK (Simple) (�3.14.6)."
  13274. */
  13275. xmlSchemaPAttrUseErr4(pctxt,
  13276. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
  13277. WXS_ITEM_NODE(item), item, cur,
  13278. "The attribute declaration's %s "
  13279. "is not validly derived from "
  13280. "the corresponding %s of the "
  13281. "attribute declaration in the %s %s",
  13282. xmlSchemaGetComponentDesignation(&strA,
  13283. WXS_ATTRUSE_TYPEDEF(cur)),
  13284. xmlSchemaGetComponentDesignation(&strB,
  13285. WXS_ATTRUSE_TYPEDEF(bcur)),
  13286. WXS_ACTION_STR(action),
  13287. xmlSchemaGetComponentDesignation(&strC, baseItem));
  13288. /* xmlSchemaGetComponentDesignation(&str, baseItem), */
  13289. FREE_AND_NULL(strA);
  13290. FREE_AND_NULL(strB);
  13291. FREE_AND_NULL(strC);
  13292. /* err = pctxt->err; */
  13293. } else {
  13294. /*
  13295. * 2.1.3 [Definition:] Let the effective value
  13296. * constraint of an attribute use be its {value
  13297. * constraint}, if present, otherwise its {attribute
  13298. * declaration}'s {value constraint} .
  13299. */
  13300. xmlSchemaGetEffectiveValueConstraint(bcur,
  13301. &effFixed, &bEffValue, NULL);
  13302. /*
  13303. * 2.1.3 ... one of the following must be true
  13304. *
  13305. * 2.1.3.1 B's �effective value constraint� is
  13306. * �absent� or default.
  13307. */
  13308. if ((bEffValue != NULL) &&
  13309. (effFixed == 1)) {
  13310. const xmlChar *rEffValue = NULL;
  13311. xmlSchemaGetEffectiveValueConstraint(bcur,
  13312. &effFixed, &rEffValue, NULL);
  13313. /*
  13314. * 2.1.3.2 R's �effective value constraint� is
  13315. * fixed with the same string as B's.
  13316. * MAYBE TODO: Compare the computed values.
  13317. * Hmm, it says "same string" so
  13318. * string-equality might really be sufficient.
  13319. */
  13320. if ((effFixed == 0) ||
  13321. (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
  13322. {
  13323. xmlChar *str = NULL;
  13324. xmlSchemaPAttrUseErr4(pctxt,
  13325. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
  13326. WXS_ITEM_NODE(item), item, cur,
  13327. "The effective value constraint of the "
  13328. "attribute use is inconsistent with "
  13329. "its correspondent in the %s %s",
  13330. WXS_ACTION_STR(action),
  13331. xmlSchemaGetComponentDesignation(&str,
  13332. baseItem),
  13333. NULL, NULL);
  13334. FREE_AND_NULL(str);
  13335. /* err = pctxt->err; */
  13336. }
  13337. }
  13338. }
  13339. break;
  13340. }
  13341. }
  13342. not_found:
  13343. if (!found) {
  13344. /*
  13345. * (2.2) "otherwise the {base type definition} must have an
  13346. * {attribute wildcard} and the {target namespace} of the
  13347. * R's {attribute declaration} must be �valid� with respect
  13348. * to that wildcard, as defined in Wildcard allows Namespace
  13349. * Name (�3.10.4)."
  13350. */
  13351. if ((baseWild == NULL) ||
  13352. (xmlSchemaCheckCVCWildcardNamespace(baseWild,
  13353. (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
  13354. {
  13355. xmlChar *str = NULL;
  13356. xmlSchemaPAttrUseErr4(pctxt,
  13357. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
  13358. WXS_ITEM_NODE(item), item, cur,
  13359. "Neither a matching attribute use, "
  13360. "nor a matching wildcard exists in the %s %s",
  13361. WXS_ACTION_STR(action),
  13362. xmlSchemaGetComponentDesignation(&str, baseItem),
  13363. NULL, NULL);
  13364. FREE_AND_NULL(str);
  13365. /* err = pctxt->err; */
  13366. }
  13367. }
  13368. }
  13369. }
  13370. /*
  13371. * SPEC derivation-ok-restriction (3):
  13372. * (3) "For each attribute use in the {attribute uses} of the {base type
  13373. * definition} whose {required} is true, there must be an attribute
  13374. * use with an {attribute declaration} with the same {name} and
  13375. * {target namespace} as its {attribute declaration} in the {attribute
  13376. * uses} of the complex type definition itself whose {required} is true.
  13377. */
  13378. if (baseUses != NULL) {
  13379. for (j = 0; j < baseUses->nbItems; j++) {
  13380. bcur = baseUses->items[j];
  13381. if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
  13382. continue;
  13383. found = 0;
  13384. if (uses != NULL) {
  13385. for (i = 0; i < uses->nbItems; i++) {
  13386. cur = uses->items[i];
  13387. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13388. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13389. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13390. WXS_ATTRUSE_DECL_TNS(bcur))) {
  13391. found = 1;
  13392. break;
  13393. }
  13394. }
  13395. }
  13396. if (!found) {
  13397. xmlChar *strA = NULL, *strB = NULL;
  13398. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13399. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
  13400. NULL, item,
  13401. "A matching attribute use for the "
  13402. "'required' %s of the %s %s is missing",
  13403. xmlSchemaGetComponentDesignation(&strA, bcur),
  13404. WXS_ACTION_STR(action),
  13405. xmlSchemaGetComponentDesignation(&strB, baseItem),
  13406. NULL);
  13407. FREE_AND_NULL(strA);
  13408. FREE_AND_NULL(strB);
  13409. }
  13410. }
  13411. }
  13412. /*
  13413. * derivation-ok-restriction (4)
  13414. */
  13415. if (wild != NULL) {
  13416. /*
  13417. * (4) "If there is an {attribute wildcard}, all of the
  13418. * following must be true:"
  13419. */
  13420. if (baseWild == NULL) {
  13421. xmlChar *str = NULL;
  13422. /*
  13423. * (4.1) "The {base type definition} must also have one."
  13424. */
  13425. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13426. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
  13427. NULL, item,
  13428. "The %s has an attribute wildcard, "
  13429. "but the %s %s '%s' does not have one",
  13430. WXS_ITEM_TYPE_NAME(item),
  13431. WXS_ACTION_STR(action),
  13432. WXS_ITEM_TYPE_NAME(baseItem),
  13433. xmlSchemaGetComponentQName(&str, baseItem));
  13434. FREE_AND_NULL(str);
  13435. return(pctxt->err);
  13436. } else if ((baseWild->any == 0) &&
  13437. xmlSchemaCheckCOSNSSubset(wild, baseWild))
  13438. {
  13439. xmlChar *str = NULL;
  13440. /*
  13441. * (4.2) "The complex type definition's {attribute wildcard}'s
  13442. * {namespace constraint} must be a subset of the {base type
  13443. * definition}'s {attribute wildcard}'s {namespace constraint},
  13444. * as defined by Wildcard Subset (�3.10.6)."
  13445. */
  13446. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13447. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
  13448. NULL, item,
  13449. "The attribute wildcard is not a valid "
  13450. "subset of the wildcard in the %s %s '%s'",
  13451. WXS_ACTION_STR(action),
  13452. WXS_ITEM_TYPE_NAME(baseItem),
  13453. xmlSchemaGetComponentQName(&str, baseItem),
  13454. NULL);
  13455. FREE_AND_NULL(str);
  13456. return(pctxt->err);
  13457. }
  13458. /* 4.3 Unless the {base type definition} is the �ur-type
  13459. * definition�, the complex type definition's {attribute
  13460. * wildcard}'s {process contents} must be identical to or
  13461. * stronger than the {base type definition}'s {attribute
  13462. * wildcard}'s {process contents}, where strict is stronger
  13463. * than lax is stronger than skip.
  13464. */
  13465. if ((! WXS_IS_ANYTYPE(baseItem)) &&
  13466. (wild->processContents < baseWild->processContents)) {
  13467. xmlChar *str = NULL;
  13468. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13469. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
  13470. NULL, baseItem,
  13471. "The {process contents} of the attribute wildcard is "
  13472. "weaker than the one in the %s %s '%s'",
  13473. WXS_ACTION_STR(action),
  13474. WXS_ITEM_TYPE_NAME(baseItem),
  13475. xmlSchemaGetComponentQName(&str, baseItem),
  13476. NULL);
  13477. FREE_AND_NULL(str)
  13478. return(pctxt->err);
  13479. }
  13480. }
  13481. return(0);
  13482. }
  13483. static int
  13484. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  13485. xmlSchemaBasicItemPtr item,
  13486. xmlSchemaWildcardPtr *completeWild,
  13487. xmlSchemaItemListPtr list,
  13488. xmlSchemaItemListPtr prohibs);
  13489. /**
  13490. * xmlSchemaFixupTypeAttributeUses:
  13491. * @ctxt: the schema parser context
  13492. * @type: the complex type definition
  13493. *
  13494. *
  13495. * Builds the wildcard and the attribute uses on the given complex type.
  13496. * Returns -1 if an internal error occurs, 0 otherwise.
  13497. *
  13498. * ATTENTION TODO: Experimantally this uses pointer comparisons for
  13499. * strings, so recheck this if we start to hardcode some schemata, since
  13500. * they might not be in the same dict.
  13501. * NOTE: It is allowed to "extend" the xs:anyType type.
  13502. */
  13503. static int
  13504. xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
  13505. xmlSchemaTypePtr type)
  13506. {
  13507. xmlSchemaTypePtr baseType = NULL;
  13508. xmlSchemaAttributeUsePtr use;
  13509. xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
  13510. if (type->baseType == NULL) {
  13511. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13512. "no base type");
  13513. return (-1);
  13514. }
  13515. baseType = type->baseType;
  13516. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13517. if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
  13518. return(-1);
  13519. uses = type->attrUses;
  13520. baseUses = baseType->attrUses;
  13521. /*
  13522. * Expand attribute group references. And build the 'complete'
  13523. * wildcard, i.e. intersect multiple wildcards.
  13524. * Move attribute prohibitions into a separate list.
  13525. */
  13526. if (uses != NULL) {
  13527. if (WXS_IS_RESTRICTION(type)) {
  13528. /*
  13529. * This one will transfer all attr. prohibitions
  13530. * into pctxt->attrProhibs.
  13531. */
  13532. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13533. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13534. pctxt->attrProhibs) == -1)
  13535. {
  13536. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13537. "failed to expand attributes");
  13538. }
  13539. if (pctxt->attrProhibs->nbItems != 0)
  13540. prohibs = pctxt->attrProhibs;
  13541. } else {
  13542. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13543. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13544. NULL) == -1)
  13545. {
  13546. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13547. "failed to expand attributes");
  13548. }
  13549. }
  13550. }
  13551. /*
  13552. * Inherit the attribute uses of the base type.
  13553. */
  13554. if (baseUses != NULL) {
  13555. int i, j;
  13556. xmlSchemaAttributeUseProhibPtr pro;
  13557. if (WXS_IS_RESTRICTION(type)) {
  13558. int usesCount;
  13559. xmlSchemaAttributeUsePtr tmp;
  13560. if (uses != NULL)
  13561. usesCount = uses->nbItems;
  13562. else
  13563. usesCount = 0;
  13564. /* Restriction. */
  13565. for (i = 0; i < baseUses->nbItems; i++) {
  13566. use = baseUses->items[i];
  13567. if (prohibs) {
  13568. /*
  13569. * Filter out prohibited uses.
  13570. */
  13571. for (j = 0; j < prohibs->nbItems; j++) {
  13572. pro = prohibs->items[j];
  13573. if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
  13574. (WXS_ATTRUSE_DECL_TNS(use) ==
  13575. pro->targetNamespace))
  13576. {
  13577. goto inherit_next;
  13578. }
  13579. }
  13580. }
  13581. if (usesCount) {
  13582. /*
  13583. * Filter out existing uses.
  13584. */
  13585. for (j = 0; j < usesCount; j++) {
  13586. tmp = uses->items[j];
  13587. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  13588. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  13589. (WXS_ATTRUSE_DECL_TNS(use) ==
  13590. WXS_ATTRUSE_DECL_TNS(tmp)))
  13591. {
  13592. goto inherit_next;
  13593. }
  13594. }
  13595. }
  13596. if (uses == NULL) {
  13597. type->attrUses = xmlSchemaItemListCreate();
  13598. if (type->attrUses == NULL)
  13599. goto exit_failure;
  13600. uses = type->attrUses;
  13601. }
  13602. xmlSchemaItemListAddSize(uses, 2, use);
  13603. inherit_next: {}
  13604. }
  13605. } else {
  13606. /* Extension. */
  13607. for (i = 0; i < baseUses->nbItems; i++) {
  13608. use = baseUses->items[i];
  13609. if (uses == NULL) {
  13610. type->attrUses = xmlSchemaItemListCreate();
  13611. if (type->attrUses == NULL)
  13612. goto exit_failure;
  13613. uses = type->attrUses;
  13614. }
  13615. xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
  13616. }
  13617. }
  13618. }
  13619. /*
  13620. * Shrink attr. uses.
  13621. */
  13622. if (uses) {
  13623. if (uses->nbItems == 0) {
  13624. xmlSchemaItemListFree(uses);
  13625. type->attrUses = NULL;
  13626. }
  13627. /*
  13628. * TODO: We could shrink the size of the array
  13629. * to fit the actual number of items.
  13630. */
  13631. }
  13632. /*
  13633. * Compute the complete wildcard.
  13634. */
  13635. if (WXS_IS_EXTENSION(type)) {
  13636. if (baseType->attributeWildcard != NULL) {
  13637. /*
  13638. * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
  13639. * the appropriate case among the following:"
  13640. */
  13641. if (type->attributeWildcard != NULL) {
  13642. /*
  13643. * Union the complete wildcard with the base wildcard.
  13644. * SPEC {attribute wildcard}
  13645. * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
  13646. * and {annotation} are those of the �complete wildcard�,
  13647. * and whose {namespace constraint} is the intensional union
  13648. * of the {namespace constraint} of the �complete wildcard�
  13649. * and of the �base wildcard�, as defined in Attribute
  13650. * Wildcard Union (�3.10.6)."
  13651. */
  13652. if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
  13653. baseType->attributeWildcard) == -1)
  13654. goto exit_failure;
  13655. } else {
  13656. /*
  13657. * (3.2.2.1.1) "If the �complete wildcard� is �absent�,
  13658. * then the �base wildcard�."
  13659. */
  13660. type->attributeWildcard = baseType->attributeWildcard;
  13661. }
  13662. } else {
  13663. /*
  13664. * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
  13665. * �complete wildcard"
  13666. * NOOP
  13667. */
  13668. }
  13669. } else {
  13670. /*
  13671. * SPEC {attribute wildcard}
  13672. * (3.1) "If the <restriction> alternative is chosen, then the
  13673. * �complete wildcard�;"
  13674. * NOOP
  13675. */
  13676. }
  13677. return (0);
  13678. exit_failure:
  13679. return(-1);
  13680. }
  13681. /**
  13682. * xmlSchemaTypeFinalContains:
  13683. * @schema: the schema
  13684. * @type: the type definition
  13685. * @final: the final
  13686. *
  13687. * Evaluates if a type definition contains the given "final".
  13688. * This does take "finalDefault" into account as well.
  13689. *
  13690. * Returns 1 if the type does containt the given "final",
  13691. * 0 otherwise.
  13692. */
  13693. static int
  13694. xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
  13695. {
  13696. if (type == NULL)
  13697. return (0);
  13698. if (type->flags & final)
  13699. return (1);
  13700. else
  13701. return (0);
  13702. }
  13703. /**
  13704. * xmlSchemaGetUnionSimpleTypeMemberTypes:
  13705. * @type: the Union Simple Type
  13706. *
  13707. * Returns a list of member types of @type if existing,
  13708. * returns NULL otherwise.
  13709. */
  13710. static xmlSchemaTypeLinkPtr
  13711. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
  13712. {
  13713. while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
  13714. if (type->memberTypes != NULL)
  13715. return (type->memberTypes);
  13716. else
  13717. type = type->baseType;
  13718. }
  13719. return (NULL);
  13720. }
  13721. /**
  13722. * xmlSchemaGetParticleTotalRangeMin:
  13723. * @particle: the particle
  13724. *
  13725. * Schema Component Constraint: Effective Total Range
  13726. * (all and sequence) + (choice)
  13727. *
  13728. * Returns the minimun Effective Total Range.
  13729. */
  13730. static int
  13731. xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
  13732. {
  13733. if ((particle->children == NULL) ||
  13734. (particle->minOccurs == 0))
  13735. return (0);
  13736. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13737. int min = -1, cur;
  13738. xmlSchemaParticlePtr part =
  13739. (xmlSchemaParticlePtr) particle->children->children;
  13740. if (part == NULL)
  13741. return (0);
  13742. while (part != NULL) {
  13743. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13744. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13745. cur = part->minOccurs;
  13746. else
  13747. cur = xmlSchemaGetParticleTotalRangeMin(part);
  13748. if (cur == 0)
  13749. return (0);
  13750. if ((min > cur) || (min == -1))
  13751. min = cur;
  13752. part = (xmlSchemaParticlePtr) part->next;
  13753. }
  13754. return (particle->minOccurs * min);
  13755. } else {
  13756. /* <all> and <sequence> */
  13757. int sum = 0;
  13758. xmlSchemaParticlePtr part =
  13759. (xmlSchemaParticlePtr) particle->children->children;
  13760. if (part == NULL)
  13761. return (0);
  13762. do {
  13763. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13764. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13765. sum += part->minOccurs;
  13766. else
  13767. sum += xmlSchemaGetParticleTotalRangeMin(part);
  13768. part = (xmlSchemaParticlePtr) part->next;
  13769. } while (part != NULL);
  13770. return (particle->minOccurs * sum);
  13771. }
  13772. }
  13773. #if 0
  13774. /**
  13775. * xmlSchemaGetParticleTotalRangeMax:
  13776. * @particle: the particle
  13777. *
  13778. * Schema Component Constraint: Effective Total Range
  13779. * (all and sequence) + (choice)
  13780. *
  13781. * Returns the maximum Effective Total Range.
  13782. */
  13783. static int
  13784. xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
  13785. {
  13786. if ((particle->children == NULL) ||
  13787. (particle->children->children == NULL))
  13788. return (0);
  13789. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13790. int max = -1, cur;
  13791. xmlSchemaParticlePtr part =
  13792. (xmlSchemaParticlePtr) particle->children->children;
  13793. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13794. if (part->children == NULL)
  13795. continue;
  13796. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13797. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13798. cur = part->maxOccurs;
  13799. else
  13800. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13801. if (cur == UNBOUNDED)
  13802. return (UNBOUNDED);
  13803. if ((max < cur) || (max == -1))
  13804. max = cur;
  13805. }
  13806. /* TODO: Handle overflows? */
  13807. return (particle->maxOccurs * max);
  13808. } else {
  13809. /* <all> and <sequence> */
  13810. int sum = 0, cur;
  13811. xmlSchemaParticlePtr part =
  13812. (xmlSchemaParticlePtr) particle->children->children;
  13813. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13814. if (part->children == NULL)
  13815. continue;
  13816. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13817. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13818. cur = part->maxOccurs;
  13819. else
  13820. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13821. if (cur == UNBOUNDED)
  13822. return (UNBOUNDED);
  13823. if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
  13824. return (UNBOUNDED);
  13825. sum += cur;
  13826. }
  13827. /* TODO: Handle overflows? */
  13828. return (particle->maxOccurs * sum);
  13829. }
  13830. }
  13831. #endif
  13832. /**
  13833. * xmlSchemaIsParticleEmptiable:
  13834. * @particle: the particle
  13835. *
  13836. * Schema Component Constraint: Particle Emptiable
  13837. * Checks whether the given particle is emptiable.
  13838. *
  13839. * Returns 1 if emptiable, 0 otherwise.
  13840. */
  13841. static int
  13842. xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
  13843. {
  13844. /*
  13845. * SPEC (1) "Its {min occurs} is 0."
  13846. */
  13847. if ((particle == NULL) || (particle->minOccurs == 0) ||
  13848. (particle->children == NULL))
  13849. return (1);
  13850. /*
  13851. * SPEC (2) "Its {term} is a group and the minimum part of the
  13852. * effective total range of that group, [...] is 0."
  13853. */
  13854. if (WXS_IS_MODEL_GROUP(particle->children)) {
  13855. if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
  13856. return (1);
  13857. }
  13858. return (0);
  13859. }
  13860. /**
  13861. * xmlSchemaCheckCOSSTDerivedOK:
  13862. * @actxt: a context
  13863. * @type: the derived simple type definition
  13864. * @baseType: the base type definition
  13865. * @subset: the subset of ('restriction', ect.)
  13866. *
  13867. * Schema Component Constraint:
  13868. * Type Derivation OK (Simple) (cos-st-derived-OK)
  13869. *
  13870. * Checks wheter @type can be validly
  13871. * derived from @baseType.
  13872. *
  13873. * Returns 0 on success, an positive error code otherwise.
  13874. */
  13875. static int
  13876. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  13877. xmlSchemaTypePtr type,
  13878. xmlSchemaTypePtr baseType,
  13879. int subset)
  13880. {
  13881. /*
  13882. * 1 They are the same type definition.
  13883. * TODO: The identy check might have to be more complex than this.
  13884. */
  13885. if (type == baseType)
  13886. return (0);
  13887. /*
  13888. * 2.1 restriction is not in the subset, or in the {final}
  13889. * of its own {base type definition};
  13890. *
  13891. * NOTE that this will be used also via "xsi:type".
  13892. *
  13893. * TODO: Revise this, it looks strange. How can the "type"
  13894. * not be fixed or *in* fixing?
  13895. */
  13896. if (WXS_IS_TYPE_NOT_FIXED(type))
  13897. if (xmlSchemaTypeFixup(type, actxt) == -1)
  13898. return(-1);
  13899. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13900. if (xmlSchemaTypeFixup(baseType, actxt) == -1)
  13901. return(-1);
  13902. if ((subset & SUBSET_RESTRICTION) ||
  13903. (xmlSchemaTypeFinalContains(type->baseType,
  13904. XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
  13905. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
  13906. }
  13907. /* 2.2 */
  13908. if (type->baseType == baseType) {
  13909. /*
  13910. * 2.2.1 D's �base type definition� is B.
  13911. */
  13912. return (0);
  13913. }
  13914. /*
  13915. * 2.2.2 D's �base type definition� is not the �ur-type definition�
  13916. * and is validly derived from B given the subset, as defined by this
  13917. * constraint.
  13918. */
  13919. if ((! WXS_IS_ANYTYPE(type->baseType)) &&
  13920. (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  13921. baseType, subset) == 0)) {
  13922. return (0);
  13923. }
  13924. /*
  13925. * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
  13926. * definition�.
  13927. */
  13928. if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
  13929. (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
  13930. return (0);
  13931. }
  13932. /*
  13933. * 2.2.4 B's {variety} is union and D is validly derived from a type
  13934. * definition in B's {member type definitions} given the subset, as
  13935. * defined by this constraint.
  13936. *
  13937. * NOTE: This seems not to involve built-in types, since there is no
  13938. * built-in Union Simple Type.
  13939. */
  13940. if (WXS_IS_UNION(baseType)) {
  13941. xmlSchemaTypeLinkPtr cur;
  13942. cur = baseType->memberTypes;
  13943. while (cur != NULL) {
  13944. if (WXS_IS_TYPE_NOT_FIXED(cur->type))
  13945. if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
  13946. return(-1);
  13947. if (xmlSchemaCheckCOSSTDerivedOK(actxt,
  13948. type, cur->type, subset) == 0)
  13949. {
  13950. /*
  13951. * It just has to be validly derived from at least one
  13952. * member-type.
  13953. */
  13954. return (0);
  13955. }
  13956. cur = cur->next;
  13957. }
  13958. }
  13959. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
  13960. }
  13961. /**
  13962. * xmlSchemaCheckTypeDefCircularInternal:
  13963. * @pctxt: the schema parser context
  13964. * @ctxtType: the type definition
  13965. * @ancestor: an ancestor of @ctxtType
  13966. *
  13967. * Checks st-props-correct (2) + ct-props-correct (3).
  13968. * Circular type definitions are not allowed.
  13969. *
  13970. * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
  13971. * circular, 0 otherwise.
  13972. */
  13973. static int
  13974. xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
  13975. xmlSchemaTypePtr ctxtType,
  13976. xmlSchemaTypePtr ancestor)
  13977. {
  13978. int ret;
  13979. if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
  13980. return (0);
  13981. if (ctxtType == ancestor) {
  13982. xmlSchemaPCustomErr(pctxt,
  13983. XML_SCHEMAP_ST_PROPS_CORRECT_2,
  13984. WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
  13985. "The definition is circular", NULL);
  13986. return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
  13987. }
  13988. if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
  13989. /*
  13990. * Avoid inifinite recursion on circular types not yet checked.
  13991. */
  13992. return (0);
  13993. }
  13994. ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
  13995. ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
  13996. ancestor->baseType);
  13997. ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
  13998. return (ret);
  13999. }
  14000. /**
  14001. * xmlSchemaCheckTypeDefCircular:
  14002. * @item: the complex/simple type definition
  14003. * @ctxt: the parser context
  14004. * @name: the name
  14005. *
  14006. * Checks for circular type definitions.
  14007. */
  14008. static void
  14009. xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
  14010. xmlSchemaParserCtxtPtr ctxt)
  14011. {
  14012. if ((item == NULL) ||
  14013. (item->type == XML_SCHEMA_TYPE_BASIC) ||
  14014. (item->baseType == NULL))
  14015. return;
  14016. xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
  14017. item->baseType);
  14018. }
  14019. /*
  14020. * Simple Type Definition Representation OK (src-simple-type) 4
  14021. *
  14022. * "4 Circular union type definition is disallowed. That is, if the
  14023. * <union> alternative is chosen, there must not be any entries in the
  14024. * memberTypes [attribute] at any depth which resolve to the component
  14025. * corresponding to the <simpleType>."
  14026. *
  14027. * Note that this should work on the *representation* of a component,
  14028. * thus assumes any union types in the member types not being yet
  14029. * substituted. At this stage we need the variety of the types
  14030. * to be already computed.
  14031. */
  14032. static int
  14033. xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
  14034. xmlSchemaTypePtr ctxType,
  14035. xmlSchemaTypeLinkPtr members)
  14036. {
  14037. xmlSchemaTypeLinkPtr member;
  14038. xmlSchemaTypePtr memberType;
  14039. member = members;
  14040. while (member != NULL) {
  14041. memberType = member->type;
  14042. while ((memberType != NULL) &&
  14043. (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
  14044. if (memberType == ctxType) {
  14045. xmlSchemaPCustomErr(pctxt,
  14046. XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
  14047. WXS_BASIC_CAST ctxType, NULL,
  14048. "The union type definition is circular", NULL);
  14049. return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
  14050. }
  14051. if ((WXS_IS_UNION(memberType)) &&
  14052. ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
  14053. {
  14054. int res;
  14055. memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
  14056. res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
  14057. ctxType,
  14058. xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
  14059. memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14060. if (res != 0)
  14061. return(res);
  14062. }
  14063. memberType = memberType->baseType;
  14064. }
  14065. member = member->next;
  14066. }
  14067. return(0);
  14068. }
  14069. static int
  14070. xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
  14071. xmlSchemaTypePtr type)
  14072. {
  14073. if (! WXS_IS_UNION(type))
  14074. return(0);
  14075. return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
  14076. type->memberTypes));
  14077. }
  14078. /**
  14079. * xmlSchemaResolveTypeReferences:
  14080. * @item: the complex/simple type definition
  14081. * @ctxt: the parser context
  14082. * @name: the name
  14083. *
  14084. * Resolvese type definition references
  14085. */
  14086. static void
  14087. xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
  14088. xmlSchemaParserCtxtPtr ctxt)
  14089. {
  14090. if (typeDef == NULL)
  14091. return;
  14092. /*
  14093. * Resolve the base type.
  14094. */
  14095. if (typeDef->baseType == NULL) {
  14096. typeDef->baseType = xmlSchemaGetType(ctxt->schema,
  14097. typeDef->base, typeDef->baseNs);
  14098. if (typeDef->baseType == NULL) {
  14099. xmlSchemaPResCompAttrErr(ctxt,
  14100. XML_SCHEMAP_SRC_RESOLVE,
  14101. WXS_BASIC_CAST typeDef, typeDef->node,
  14102. "base", typeDef->base, typeDef->baseNs,
  14103. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14104. return;
  14105. }
  14106. }
  14107. if (WXS_IS_SIMPLE(typeDef)) {
  14108. if (WXS_IS_UNION(typeDef)) {
  14109. /*
  14110. * Resolve the memberTypes.
  14111. */
  14112. xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
  14113. return;
  14114. } else if (WXS_IS_LIST(typeDef)) {
  14115. /*
  14116. * Resolve the itemType.
  14117. */
  14118. if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
  14119. typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
  14120. typeDef->base, typeDef->baseNs);
  14121. if ((typeDef->subtypes == NULL) ||
  14122. (! WXS_IS_SIMPLE(typeDef->subtypes)))
  14123. {
  14124. typeDef->subtypes = NULL;
  14125. xmlSchemaPResCompAttrErr(ctxt,
  14126. XML_SCHEMAP_SRC_RESOLVE,
  14127. WXS_BASIC_CAST typeDef, typeDef->node,
  14128. "itemType", typeDef->base, typeDef->baseNs,
  14129. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14130. }
  14131. }
  14132. return;
  14133. }
  14134. }
  14135. /*
  14136. * The ball of letters below means, that if we have a particle
  14137. * which has a QName-helper component as its {term}, we want
  14138. * to resolve it...
  14139. */
  14140. else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
  14141. ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
  14142. XML_SCHEMA_TYPE_PARTICLE) &&
  14143. (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
  14144. ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
  14145. XML_SCHEMA_EXTRA_QNAMEREF))
  14146. {
  14147. xmlSchemaQNameRefPtr ref =
  14148. WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
  14149. xmlSchemaModelGroupDefPtr groupDef;
  14150. /*
  14151. * URGENT TODO: Test this.
  14152. */
  14153. WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
  14154. /*
  14155. * Resolve the MG definition reference.
  14156. */
  14157. groupDef =
  14158. WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
  14159. ref->itemType, ref->name, ref->targetNamespace);
  14160. if (groupDef == NULL) {
  14161. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  14162. NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
  14163. "ref", ref->name, ref->targetNamespace, ref->itemType,
  14164. NULL);
  14165. /* Remove the particle. */
  14166. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14167. } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
  14168. /* Remove the particle. */
  14169. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14170. else {
  14171. /*
  14172. * Assign the MG definition's {model group} to the
  14173. * particle's {term}.
  14174. */
  14175. WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
  14176. if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
  14177. /*
  14178. * SPEC cos-all-limited (1.2)
  14179. * "1.2 the {term} property of a particle with
  14180. * {max occurs}=1 which is part of a pair which constitutes
  14181. * the {content type} of a complex type definition."
  14182. */
  14183. if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
  14184. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  14185. /* TODO: error code */
  14186. XML_SCHEMAP_COS_ALL_LIMITED,
  14187. WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
  14188. "The particle's {max occurs} must be 1, since the "
  14189. "reference resolves to an 'all' model group",
  14190. NULL, NULL);
  14191. }
  14192. }
  14193. }
  14194. }
  14195. }
  14196. /**
  14197. * xmlSchemaCheckSTPropsCorrect:
  14198. * @ctxt: the schema parser context
  14199. * @type: the simple type definition
  14200. *
  14201. * Checks st-props-correct.
  14202. *
  14203. * Returns 0 if the properties are correct,
  14204. * if not, a positive error code and -1 on internal
  14205. * errors.
  14206. */
  14207. static int
  14208. xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  14209. xmlSchemaTypePtr type)
  14210. {
  14211. xmlSchemaTypePtr baseType = type->baseType;
  14212. xmlChar *str = NULL;
  14213. /* STATE: error funcs converted. */
  14214. /*
  14215. * Schema Component Constraint: Simple Type Definition Properties Correct
  14216. *
  14217. * NOTE: This is somehow redundant, since we actually built a simple type
  14218. * to have all the needed information; this acts as an self test.
  14219. */
  14220. /* Base type: If the datatype has been �derived� by �restriction�
  14221. * then the Simple Type Definition component from which it is �derived�,
  14222. * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
  14223. */
  14224. if (baseType == NULL) {
  14225. /*
  14226. * TODO: Think about: "modulo the impact of Missing
  14227. * Sub-components (�5.3)."
  14228. */
  14229. xmlSchemaPCustomErr(ctxt,
  14230. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14231. WXS_BASIC_CAST type, NULL,
  14232. "No base type existent", NULL);
  14233. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14234. }
  14235. if (! WXS_IS_SIMPLE(baseType)) {
  14236. xmlSchemaPCustomErr(ctxt,
  14237. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14238. WXS_BASIC_CAST type, NULL,
  14239. "The base type '%s' is not a simple type",
  14240. xmlSchemaGetComponentQName(&str, baseType));
  14241. FREE_AND_NULL(str)
  14242. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14243. }
  14244. if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
  14245. (WXS_IS_RESTRICTION(type) == 0) &&
  14246. (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
  14247. xmlSchemaPCustomErr(ctxt,
  14248. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14249. WXS_BASIC_CAST type, NULL,
  14250. "A type, derived by list or union, must have "
  14251. "the simple ur-type definition as base type, not '%s'",
  14252. xmlSchemaGetComponentQName(&str, baseType));
  14253. FREE_AND_NULL(str)
  14254. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14255. }
  14256. /*
  14257. * Variety: One of {atomic, list, union}.
  14258. */
  14259. if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
  14260. (! WXS_IS_LIST(type))) {
  14261. xmlSchemaPCustomErr(ctxt,
  14262. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14263. WXS_BASIC_CAST type, NULL,
  14264. "The variety is absent", NULL);
  14265. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14266. }
  14267. /* TODO: Finish this. Hmm, is this finished? */
  14268. /*
  14269. * 3 The {final} of the {base type definition} must not contain restriction.
  14270. */
  14271. if (xmlSchemaTypeFinalContains(baseType,
  14272. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14273. xmlSchemaPCustomErr(ctxt,
  14274. XML_SCHEMAP_ST_PROPS_CORRECT_3,
  14275. WXS_BASIC_CAST type, NULL,
  14276. "The 'final' of its base type '%s' must not contain "
  14277. "'restriction'",
  14278. xmlSchemaGetComponentQName(&str, baseType));
  14279. FREE_AND_NULL(str)
  14280. return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
  14281. }
  14282. /*
  14283. * 2 All simple type definitions must be derived ultimately from the �simple
  14284. * ur-type definition (so� circular definitions are disallowed). That is, it
  14285. * must be possible to reach a built-in primitive datatype or the �simple
  14286. * ur-type definition� by repeatedly following the {base type definition}.
  14287. *
  14288. * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
  14289. */
  14290. return (0);
  14291. }
  14292. /**
  14293. * xmlSchemaCheckCOSSTRestricts:
  14294. * @ctxt: the schema parser context
  14295. * @type: the simple type definition
  14296. *
  14297. * Schema Component Constraint:
  14298. * Derivation Valid (Restriction, Simple) (cos-st-restricts)
  14299. * Checks if the given @type (simpleType) is derived validly by restriction.
  14300. * STATUS:
  14301. *
  14302. * Returns -1 on internal errors, 0 if the type is validly derived,
  14303. * a positive error code otherwise.
  14304. */
  14305. static int
  14306. xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
  14307. xmlSchemaTypePtr type)
  14308. {
  14309. xmlChar *str = NULL;
  14310. if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
  14311. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14312. "given type is not a user-derived simpleType");
  14313. return (-1);
  14314. }
  14315. if (WXS_IS_ATOMIC(type)) {
  14316. xmlSchemaTypePtr primitive;
  14317. /*
  14318. * 1.1 The {base type definition} must be an atomic simple
  14319. * type definition or a built-in primitive datatype.
  14320. */
  14321. if (! WXS_IS_ATOMIC(type->baseType)) {
  14322. xmlSchemaPCustomErr(pctxt,
  14323. XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
  14324. WXS_BASIC_CAST type, NULL,
  14325. "The base type '%s' is not an atomic simple type",
  14326. xmlSchemaGetComponentQName(&str, type->baseType));
  14327. FREE_AND_NULL(str)
  14328. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
  14329. }
  14330. /* 1.2 The {final} of the {base type definition} must not contain
  14331. * restriction.
  14332. */
  14333. /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
  14334. if (xmlSchemaTypeFinalContains(type->baseType,
  14335. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14336. xmlSchemaPCustomErr(pctxt,
  14337. XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
  14338. WXS_BASIC_CAST type, NULL,
  14339. "The final of its base type '%s' must not contain 'restriction'",
  14340. xmlSchemaGetComponentQName(&str, type->baseType));
  14341. FREE_AND_NULL(str)
  14342. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
  14343. }
  14344. /*
  14345. * 1.3.1 DF must be an allowed constraining facet for the {primitive
  14346. * type definition}, as specified in the appropriate subsection of 3.2
  14347. * Primitive datatypes.
  14348. */
  14349. if (type->facets != NULL) {
  14350. xmlSchemaFacetPtr facet;
  14351. int ok = 1;
  14352. primitive = xmlSchemaGetPrimitiveType(type);
  14353. if (primitive == NULL) {
  14354. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14355. "failed to get primitive type");
  14356. return (-1);
  14357. }
  14358. facet = type->facets;
  14359. do {
  14360. if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
  14361. ok = 0;
  14362. xmlSchemaPIllegalFacetAtomicErr(pctxt,
  14363. XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
  14364. type, primitive, facet);
  14365. }
  14366. facet = facet->next;
  14367. } while (facet != NULL);
  14368. if (ok == 0)
  14369. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
  14370. }
  14371. /*
  14372. * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
  14373. * of the {base type definition} (call this BF),then the DF's {value}
  14374. * must be a valid restriction of BF's {value} as defined in
  14375. * [XML Schemas: Datatypes]."
  14376. *
  14377. * NOTE (1.3.2) Facet derivation constraints are currently handled in
  14378. * xmlSchemaDeriveAndValidateFacets()
  14379. */
  14380. } else if (WXS_IS_LIST(type)) {
  14381. xmlSchemaTypePtr itemType = NULL;
  14382. itemType = type->subtypes;
  14383. if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
  14384. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14385. "failed to evaluate the item type");
  14386. return (-1);
  14387. }
  14388. if (WXS_IS_TYPE_NOT_FIXED(itemType))
  14389. xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
  14390. /*
  14391. * 2.1 The {item type definition} must have a {variety} of atomic or
  14392. * union (in which case all the {member type definitions}
  14393. * must be atomic).
  14394. */
  14395. if ((! WXS_IS_ATOMIC(itemType)) &&
  14396. (! WXS_IS_UNION(itemType))) {
  14397. xmlSchemaPCustomErr(pctxt,
  14398. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14399. WXS_BASIC_CAST type, NULL,
  14400. "The item type '%s' does not have a variety of atomic or union",
  14401. xmlSchemaGetComponentQName(&str, itemType));
  14402. FREE_AND_NULL(str)
  14403. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14404. } else if (WXS_IS_UNION(itemType)) {
  14405. xmlSchemaTypeLinkPtr member;
  14406. member = itemType->memberTypes;
  14407. while (member != NULL) {
  14408. if (! WXS_IS_ATOMIC(member->type)) {
  14409. xmlSchemaPCustomErr(pctxt,
  14410. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14411. WXS_BASIC_CAST type, NULL,
  14412. "The item type is a union type, but the "
  14413. "member type '%s' of this item type is not atomic",
  14414. xmlSchemaGetComponentQName(&str, member->type));
  14415. FREE_AND_NULL(str)
  14416. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14417. }
  14418. member = member->next;
  14419. }
  14420. }
  14421. if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
  14422. xmlSchemaFacetPtr facet;
  14423. /*
  14424. * This is the case if we have: <simpleType><list ..
  14425. */
  14426. /*
  14427. * 2.3.1
  14428. * 2.3.1.1 The {final} of the {item type definition} must not
  14429. * contain list.
  14430. */
  14431. if (xmlSchemaTypeFinalContains(itemType,
  14432. XML_SCHEMAS_TYPE_FINAL_LIST)) {
  14433. xmlSchemaPCustomErr(pctxt,
  14434. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
  14435. WXS_BASIC_CAST type, NULL,
  14436. "The final of its item type '%s' must not contain 'list'",
  14437. xmlSchemaGetComponentQName(&str, itemType));
  14438. FREE_AND_NULL(str)
  14439. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
  14440. }
  14441. /*
  14442. * 2.3.1.2 The {facets} must only contain the whiteSpace
  14443. * facet component.
  14444. * OPTIMIZE TODO: the S4S already disallows any facet
  14445. * to be specified.
  14446. */
  14447. if (type->facets != NULL) {
  14448. facet = type->facets;
  14449. do {
  14450. if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
  14451. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14452. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
  14453. type, facet);
  14454. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
  14455. }
  14456. facet = facet->next;
  14457. } while (facet != NULL);
  14458. }
  14459. /*
  14460. * MAYBE TODO: (Hmm, not really) Datatypes states:
  14461. * A �list� datatype can be �derived� from an �atomic� datatype
  14462. * whose �lexical space� allows space (such as string or anyURI)or
  14463. * a �union� datatype any of whose {member type definitions}'s
  14464. * �lexical space� allows space.
  14465. */
  14466. } else {
  14467. /*
  14468. * This is the case if we have: <simpleType><restriction ...
  14469. * I.e. the variety of "list" is inherited.
  14470. */
  14471. /*
  14472. * 2.3.2
  14473. * 2.3.2.1 The {base type definition} must have a {variety} of list.
  14474. */
  14475. if (! WXS_IS_LIST(type->baseType)) {
  14476. xmlSchemaPCustomErr(pctxt,
  14477. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
  14478. WXS_BASIC_CAST type, NULL,
  14479. "The base type '%s' must be a list type",
  14480. xmlSchemaGetComponentQName(&str, type->baseType));
  14481. FREE_AND_NULL(str)
  14482. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
  14483. }
  14484. /*
  14485. * 2.3.2.2 The {final} of the {base type definition} must not
  14486. * contain restriction.
  14487. */
  14488. if (xmlSchemaTypeFinalContains(type->baseType,
  14489. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14490. xmlSchemaPCustomErr(pctxt,
  14491. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
  14492. WXS_BASIC_CAST type, NULL,
  14493. "The 'final' of the base type '%s' must not contain 'restriction'",
  14494. xmlSchemaGetComponentQName(&str, type->baseType));
  14495. FREE_AND_NULL(str)
  14496. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
  14497. }
  14498. /*
  14499. * 2.3.2.3 The {item type definition} must be validly derived
  14500. * from the {base type definition}'s {item type definition} given
  14501. * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
  14502. */
  14503. {
  14504. xmlSchemaTypePtr baseItemType;
  14505. baseItemType = type->baseType->subtypes;
  14506. if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
  14507. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14508. "failed to eval the item type of a base type");
  14509. return (-1);
  14510. }
  14511. if ((itemType != baseItemType) &&
  14512. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
  14513. baseItemType, 0) != 0)) {
  14514. xmlChar *strBIT = NULL, *strBT = NULL;
  14515. xmlSchemaPCustomErrExt(pctxt,
  14516. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
  14517. WXS_BASIC_CAST type, NULL,
  14518. "The item type '%s' is not validly derived from "
  14519. "the item type '%s' of the base type '%s'",
  14520. xmlSchemaGetComponentQName(&str, itemType),
  14521. xmlSchemaGetComponentQName(&strBIT, baseItemType),
  14522. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14523. FREE_AND_NULL(str)
  14524. FREE_AND_NULL(strBIT)
  14525. FREE_AND_NULL(strBT)
  14526. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
  14527. }
  14528. }
  14529. if (type->facets != NULL) {
  14530. xmlSchemaFacetPtr facet;
  14531. int ok = 1;
  14532. /*
  14533. * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
  14534. * and enumeration facet components are allowed among the {facets}.
  14535. */
  14536. facet = type->facets;
  14537. do {
  14538. switch (facet->type) {
  14539. case XML_SCHEMA_FACET_LENGTH:
  14540. case XML_SCHEMA_FACET_MINLENGTH:
  14541. case XML_SCHEMA_FACET_MAXLENGTH:
  14542. case XML_SCHEMA_FACET_WHITESPACE:
  14543. /*
  14544. * TODO: 2.5.1.2 List datatypes
  14545. * The value of �whiteSpace� is fixed to the value collapse.
  14546. */
  14547. case XML_SCHEMA_FACET_PATTERN:
  14548. case XML_SCHEMA_FACET_ENUMERATION:
  14549. break;
  14550. default: {
  14551. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14552. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
  14553. type, facet);
  14554. /*
  14555. * We could return, but it's nicer to report all
  14556. * invalid facets.
  14557. */
  14558. ok = 0;
  14559. }
  14560. }
  14561. facet = facet->next;
  14562. } while (facet != NULL);
  14563. if (ok == 0)
  14564. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
  14565. /*
  14566. * SPEC (2.3.2.5) (same as 1.3.2)
  14567. *
  14568. * NOTE (2.3.2.5) This is currently done in
  14569. * xmlSchemaDeriveAndValidateFacets()
  14570. */
  14571. }
  14572. }
  14573. } else if (WXS_IS_UNION(type)) {
  14574. /*
  14575. * 3.1 The {member type definitions} must all have {variety} of
  14576. * atomic or list.
  14577. */
  14578. xmlSchemaTypeLinkPtr member;
  14579. member = type->memberTypes;
  14580. while (member != NULL) {
  14581. if (WXS_IS_TYPE_NOT_FIXED(member->type))
  14582. xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
  14583. if ((! WXS_IS_ATOMIC(member->type)) &&
  14584. (! WXS_IS_LIST(member->type))) {
  14585. xmlSchemaPCustomErr(pctxt,
  14586. XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
  14587. WXS_BASIC_CAST type, NULL,
  14588. "The member type '%s' is neither an atomic, nor a list type",
  14589. xmlSchemaGetComponentQName(&str, member->type));
  14590. FREE_AND_NULL(str)
  14591. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
  14592. }
  14593. member = member->next;
  14594. }
  14595. /*
  14596. * 3.3.1 If the {base type definition} is the �simple ur-type
  14597. * definition�
  14598. */
  14599. if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
  14600. /*
  14601. * 3.3.1.1 All of the {member type definitions} must have a
  14602. * {final} which does not contain union.
  14603. */
  14604. member = type->memberTypes;
  14605. while (member != NULL) {
  14606. if (xmlSchemaTypeFinalContains(member->type,
  14607. XML_SCHEMAS_TYPE_FINAL_UNION)) {
  14608. xmlSchemaPCustomErr(pctxt,
  14609. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
  14610. WXS_BASIC_CAST type, NULL,
  14611. "The 'final' of member type '%s' contains 'union'",
  14612. xmlSchemaGetComponentQName(&str, member->type));
  14613. FREE_AND_NULL(str)
  14614. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
  14615. }
  14616. member = member->next;
  14617. }
  14618. /*
  14619. * 3.3.1.2 The {facets} must be empty.
  14620. */
  14621. if (type->facetSet != NULL) {
  14622. xmlSchemaPCustomErr(pctxt,
  14623. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
  14624. WXS_BASIC_CAST type, NULL,
  14625. "No facets allowed", NULL);
  14626. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
  14627. }
  14628. } else {
  14629. /*
  14630. * 3.3.2.1 The {base type definition} must have a {variety} of union.
  14631. * I.e. the variety of "list" is inherited.
  14632. */
  14633. if (! WXS_IS_UNION(type->baseType)) {
  14634. xmlSchemaPCustomErr(pctxt,
  14635. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
  14636. WXS_BASIC_CAST type, NULL,
  14637. "The base type '%s' is not a union type",
  14638. xmlSchemaGetComponentQName(&str, type->baseType));
  14639. FREE_AND_NULL(str)
  14640. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
  14641. }
  14642. /*
  14643. * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
  14644. */
  14645. if (xmlSchemaTypeFinalContains(type->baseType,
  14646. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14647. xmlSchemaPCustomErr(pctxt,
  14648. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
  14649. WXS_BASIC_CAST type, NULL,
  14650. "The 'final' of its base type '%s' must not contain 'restriction'",
  14651. xmlSchemaGetComponentQName(&str, type->baseType));
  14652. FREE_AND_NULL(str)
  14653. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
  14654. }
  14655. /*
  14656. * 3.3.2.3 The {member type definitions}, in order, must be validly
  14657. * derived from the corresponding type definitions in the {base
  14658. * type definition}'s {member type definitions} given the empty set,
  14659. * as defined in Type Derivation OK (Simple) (�3.14.6).
  14660. */
  14661. {
  14662. xmlSchemaTypeLinkPtr baseMember;
  14663. /*
  14664. * OPTIMIZE: if the type is restricting, it has no local defined
  14665. * member types and inherits the member types of the base type;
  14666. * thus a check for equality can be skipped.
  14667. */
  14668. /*
  14669. * Even worse: I cannot see a scenario where a restricting
  14670. * union simple type can have other member types as the member
  14671. * types of it's base type. This check seems not necessary with
  14672. * respect to the derivation process in libxml2.
  14673. * But necessary if constructing types with an API.
  14674. */
  14675. if (type->memberTypes != NULL) {
  14676. member = type->memberTypes;
  14677. baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
  14678. if ((member == NULL) && (baseMember != NULL)) {
  14679. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14680. "different number of member types in base");
  14681. }
  14682. while (member != NULL) {
  14683. if (baseMember == NULL) {
  14684. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14685. "different number of member types in base");
  14686. } else if ((member->type != baseMember->type) &&
  14687. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  14688. member->type, baseMember->type, 0) != 0)) {
  14689. xmlChar *strBMT = NULL, *strBT = NULL;
  14690. xmlSchemaPCustomErrExt(pctxt,
  14691. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
  14692. WXS_BASIC_CAST type, NULL,
  14693. "The member type %s is not validly "
  14694. "derived from its corresponding member "
  14695. "type %s of the base type %s",
  14696. xmlSchemaGetComponentQName(&str, member->type),
  14697. xmlSchemaGetComponentQName(&strBMT, baseMember->type),
  14698. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14699. FREE_AND_NULL(str)
  14700. FREE_AND_NULL(strBMT)
  14701. FREE_AND_NULL(strBT)
  14702. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
  14703. }
  14704. member = member->next;
  14705. if (baseMember != NULL)
  14706. baseMember = baseMember->next;
  14707. }
  14708. }
  14709. }
  14710. /*
  14711. * 3.3.2.4 Only pattern and enumeration facet components are
  14712. * allowed among the {facets}.
  14713. */
  14714. if (type->facets != NULL) {
  14715. xmlSchemaFacetPtr facet;
  14716. int ok = 1;
  14717. facet = type->facets;
  14718. do {
  14719. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  14720. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  14721. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14722. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
  14723. type, facet);
  14724. ok = 0;
  14725. }
  14726. facet = facet->next;
  14727. } while (facet != NULL);
  14728. if (ok == 0)
  14729. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
  14730. }
  14731. /*
  14732. * SPEC (3.3.2.5) (same as 1.3.2)
  14733. *
  14734. * NOTE (3.3.2.5) This is currently done in
  14735. * xmlSchemaDeriveAndValidateFacets()
  14736. */
  14737. }
  14738. }
  14739. return (0);
  14740. }
  14741. /**
  14742. * xmlSchemaCheckSRCSimpleType:
  14743. * @ctxt: the schema parser context
  14744. * @type: the simple type definition
  14745. *
  14746. * Checks crc-simple-type constraints.
  14747. *
  14748. * Returns 0 if the constraints are satisfied,
  14749. * if not a positive error code and -1 on internal
  14750. * errors.
  14751. */
  14752. #if 0
  14753. static int
  14754. xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
  14755. xmlSchemaTypePtr type)
  14756. {
  14757. /*
  14758. * src-simple-type.1 The corresponding simple type definition, if any,
  14759. * must satisfy the conditions set out in Constraints on Simple Type
  14760. * Definition Schema Components (�3.14.6).
  14761. */
  14762. if (WXS_IS_RESTRICTION(type)) {
  14763. /*
  14764. * src-simple-type.2 "If the <restriction> alternative is chosen,
  14765. * either it must have a base [attribute] or a <simpleType> among its
  14766. * [children], but not both."
  14767. * NOTE: This is checked in the parse function of <restriction>.
  14768. */
  14769. /*
  14770. *
  14771. */
  14772. } else if (WXS_IS_LIST(type)) {
  14773. /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
  14774. * an itemType [attribute] or a <simpleType> among its [children],
  14775. * but not both."
  14776. *
  14777. * NOTE: This is checked in the parse function of <list>.
  14778. */
  14779. } else if (WXS_IS_UNION(type)) {
  14780. /*
  14781. * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
  14782. */
  14783. }
  14784. return (0);
  14785. }
  14786. #endif
  14787. static int
  14788. xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
  14789. {
  14790. if (ctxt->vctxt == NULL) {
  14791. ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
  14792. if (ctxt->vctxt == NULL) {
  14793. xmlSchemaPErr(ctxt, NULL,
  14794. XML_SCHEMAP_INTERNAL,
  14795. "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
  14796. "failed to create a temp. validation context.\n",
  14797. NULL, NULL);
  14798. return (-1);
  14799. }
  14800. /* TODO: Pass user data. */
  14801. xmlSchemaSetValidErrors(ctxt->vctxt,
  14802. ctxt->error, ctxt->warning, ctxt->errCtxt);
  14803. xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
  14804. ctxt->serror, ctxt->errCtxt);
  14805. }
  14806. return (0);
  14807. }
  14808. static int
  14809. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  14810. xmlNodePtr node,
  14811. xmlSchemaTypePtr type,
  14812. const xmlChar *value,
  14813. xmlSchemaValPtr *retVal,
  14814. int fireErrors,
  14815. int normalize,
  14816. int isNormalized);
  14817. /**
  14818. * xmlSchemaParseCheckCOSValidDefault:
  14819. * @pctxt: the schema parser context
  14820. * @type: the simple type definition
  14821. * @value: the default value
  14822. * @node: an optional node (the holder of the value)
  14823. *
  14824. * Schema Component Constraint: Element Default Valid (Immediate)
  14825. * (cos-valid-default)
  14826. * This will be used by the parser only. For the validator there's
  14827. * an other version.
  14828. *
  14829. * Returns 0 if the constraints are satisfied,
  14830. * if not, a positive error code and -1 on internal
  14831. * errors.
  14832. */
  14833. static int
  14834. xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  14835. xmlNodePtr node,
  14836. xmlSchemaTypePtr type,
  14837. const xmlChar *value,
  14838. xmlSchemaValPtr *val)
  14839. {
  14840. int ret = 0;
  14841. /*
  14842. * cos-valid-default:
  14843. * Schema Component Constraint: Element Default Valid (Immediate)
  14844. * For a string to be a valid default with respect to a type
  14845. * definition the appropriate case among the following must be true:
  14846. */
  14847. if WXS_IS_COMPLEX(type) {
  14848. /*
  14849. * Complex type.
  14850. *
  14851. * SPEC (2.1) "its {content type} must be a simple type definition
  14852. * or mixed."
  14853. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  14854. * type}'s particle must be �emptiable� as defined by
  14855. * Particle Emptiable (�3.9.6)."
  14856. */
  14857. if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
  14858. ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
  14859. /* NOTE that this covers (2.2.2) as well. */
  14860. xmlSchemaPCustomErr(pctxt,
  14861. XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
  14862. WXS_BASIC_CAST type, type->node,
  14863. "For a string to be a valid default, the type definition "
  14864. "must be a simple type or a complex type with mixed content "
  14865. "and a particle emptiable", NULL);
  14866. return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
  14867. }
  14868. }
  14869. /*
  14870. * 1 If the type definition is a simple type definition, then the string
  14871. * must be �valid� with respect to that definition as defined by String
  14872. * Valid (�3.14.4).
  14873. *
  14874. * AND
  14875. *
  14876. * 2.2.1 If the {content type} is a simple type definition, then the
  14877. * string must be �valid� with respect to that simple type definition
  14878. * as defined by String Valid (�3.14.4).
  14879. */
  14880. if (WXS_IS_SIMPLE(type))
  14881. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14882. type, value, val, 1, 1, 0);
  14883. else if (WXS_HAS_SIMPLE_CONTENT(type))
  14884. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14885. type->contentTypeDef, value, val, 1, 1, 0);
  14886. else
  14887. return (ret);
  14888. if (ret < 0) {
  14889. PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
  14890. "calling xmlSchemaVCheckCVCSimpleType()");
  14891. }
  14892. return (ret);
  14893. }
  14894. /**
  14895. * xmlSchemaCheckCTPropsCorrect:
  14896. * @ctxt: the schema parser context
  14897. * @type: the complex type definition
  14898. *
  14899. *.(4.6) Constraints on Complex Type Definition Schema Components
  14900. * Schema Component Constraint:
  14901. * Complex Type Definition Properties Correct (ct-props-correct)
  14902. * STATUS: (seems) complete
  14903. *
  14904. * Returns 0 if the constraints are satisfied, a positive
  14905. * error code if not and -1 if an internal error occured.
  14906. */
  14907. static int
  14908. xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  14909. xmlSchemaTypePtr type)
  14910. {
  14911. /*
  14912. * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
  14913. *
  14914. * SPEC (1) "The values of the properties of a complex type definition must
  14915. * be as described in the property tableau in The Complex Type Definition
  14916. * Schema Component (�3.4.1), modulo the impact of Missing
  14917. * Sub-components (�5.3)."
  14918. */
  14919. if ((type->baseType != NULL) &&
  14920. (WXS_IS_SIMPLE(type->baseType)) &&
  14921. (WXS_IS_EXTENSION(type) == 0)) {
  14922. /*
  14923. * SPEC (2) "If the {base type definition} is a simple type definition,
  14924. * the {derivation method} must be extension."
  14925. */
  14926. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14927. XML_SCHEMAP_SRC_CT_1,
  14928. NULL, WXS_BASIC_CAST type,
  14929. "If the base type is a simple type, the derivation method must be "
  14930. "'extension'", NULL, NULL);
  14931. return (XML_SCHEMAP_SRC_CT_1);
  14932. }
  14933. /*
  14934. * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
  14935. * definition�. That is, it must be possible to reach the �ur-type
  14936. * definition by repeatedly following the {base type definition}."
  14937. *
  14938. * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
  14939. */
  14940. /*
  14941. * NOTE that (4) and (5) need the following:
  14942. * - attribute uses need to be already inherited (apply attr. prohibitions)
  14943. * - attribute group references need to be expanded already
  14944. * - simple types need to be typefixed already
  14945. */
  14946. if (type->attrUses &&
  14947. (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
  14948. {
  14949. xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
  14950. xmlSchemaAttributeUsePtr use, tmp;
  14951. int i, j, hasId = 0;
  14952. for (i = uses->nbItems -1; i >= 0; i--) {
  14953. use = uses->items[i];
  14954. /*
  14955. * SPEC ct-props-correct
  14956. * (4) "Two distinct attribute declarations in the
  14957. * {attribute uses} must not have identical {name}s and
  14958. * {target namespace}s."
  14959. */
  14960. if (i > 0) {
  14961. for (j = i -1; j >= 0; j--) {
  14962. tmp = uses->items[j];
  14963. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  14964. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  14965. (WXS_ATTRUSE_DECL_TNS(use) ==
  14966. WXS_ATTRUSE_DECL_TNS(tmp)))
  14967. {
  14968. xmlChar *str = NULL;
  14969. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14970. XML_SCHEMAP_AG_PROPS_CORRECT,
  14971. NULL, WXS_BASIC_CAST type,
  14972. "Duplicate %s",
  14973. xmlSchemaGetComponentDesignation(&str, use),
  14974. NULL);
  14975. FREE_AND_NULL(str);
  14976. /*
  14977. * Remove the duplicate.
  14978. */
  14979. if (xmlSchemaItemListRemove(uses, i) == -1)
  14980. goto exit_failure;
  14981. goto next_use;
  14982. }
  14983. }
  14984. }
  14985. /*
  14986. * SPEC ct-props-correct
  14987. * (5) "Two distinct attribute declarations in the
  14988. * {attribute uses} must not have {type definition}s which
  14989. * are or are derived from ID."
  14990. */
  14991. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  14992. if (xmlSchemaIsDerivedFromBuiltInType(
  14993. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  14994. {
  14995. if (hasId) {
  14996. xmlChar *str = NULL;
  14997. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14998. XML_SCHEMAP_AG_PROPS_CORRECT,
  14999. NULL, WXS_BASIC_CAST type,
  15000. "There must not exist more than one attribute "
  15001. "declaration of type 'xs:ID' "
  15002. "(or derived from 'xs:ID'). The %s violates this "
  15003. "constraint",
  15004. xmlSchemaGetComponentDesignation(&str, use),
  15005. NULL);
  15006. FREE_AND_NULL(str);
  15007. if (xmlSchemaItemListRemove(uses, i) == -1)
  15008. goto exit_failure;
  15009. }
  15010. hasId = 1;
  15011. }
  15012. }
  15013. next_use: {}
  15014. }
  15015. }
  15016. return (0);
  15017. exit_failure:
  15018. return(-1);
  15019. }
  15020. static int
  15021. xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
  15022. xmlSchemaTypePtr typeB)
  15023. {
  15024. /*
  15025. * TODO: This should implement component-identity
  15026. * in the future.
  15027. */
  15028. if ((typeA == NULL) || (typeB == NULL))
  15029. return (0);
  15030. return (typeA == typeB);
  15031. }
  15032. /**
  15033. * xmlSchemaCheckCOSCTDerivedOK:
  15034. * @ctxt: the schema parser context
  15035. * @type: the to-be derived complex type definition
  15036. * @baseType: the base complex type definition
  15037. * @set: the given set
  15038. *
  15039. * Schema Component Constraint:
  15040. * Type Derivation OK (Complex) (cos-ct-derived-ok)
  15041. *
  15042. * STATUS: completed
  15043. *
  15044. * Returns 0 if the constraints are satisfied, or 1
  15045. * if not.
  15046. */
  15047. static int
  15048. xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15049. xmlSchemaTypePtr type,
  15050. xmlSchemaTypePtr baseType,
  15051. int set)
  15052. {
  15053. int equal = xmlSchemaAreEqualTypes(type, baseType);
  15054. /* TODO: Error codes. */
  15055. /*
  15056. * SPEC "For a complex type definition (call it D, for derived)
  15057. * to be validly derived from a type definition (call this
  15058. * B, for base) given a subset of {extension, restriction}
  15059. * all of the following must be true:"
  15060. */
  15061. if (! equal) {
  15062. /*
  15063. * SPEC (1) "If B and D are not the same type definition, then the
  15064. * {derivation method} of D must not be in the subset."
  15065. */
  15066. if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
  15067. ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
  15068. return (1);
  15069. } else {
  15070. /*
  15071. * SPEC (2.1) "B and D must be the same type definition."
  15072. */
  15073. return (0);
  15074. }
  15075. /*
  15076. * SPEC (2.2) "B must be D's {base type definition}."
  15077. */
  15078. if (type->baseType == baseType)
  15079. return (0);
  15080. /*
  15081. * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
  15082. * definition�."
  15083. */
  15084. if (WXS_IS_ANYTYPE(type->baseType))
  15085. return (1);
  15086. if (WXS_IS_COMPLEX(type->baseType)) {
  15087. /*
  15088. * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
  15089. * must be validly derived from B given the subset as defined by this
  15090. * constraint."
  15091. */
  15092. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
  15093. baseType, set));
  15094. } else {
  15095. /*
  15096. * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
  15097. * must be validly derived from B given the subset as defined in Type
  15098. * Derivation OK (Simple) (�3.14.6).
  15099. */
  15100. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  15101. baseType, set));
  15102. }
  15103. }
  15104. /**
  15105. * xmlSchemaCheckCOSDerivedOK:
  15106. * @type: the derived simple type definition
  15107. * @baseType: the base type definition
  15108. *
  15109. * Calls:
  15110. * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
  15111. *
  15112. * Checks wheter @type can be validly derived from @baseType.
  15113. *
  15114. * Returns 0 on success, an positive error code otherwise.
  15115. */
  15116. static int
  15117. xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15118. xmlSchemaTypePtr type,
  15119. xmlSchemaTypePtr baseType,
  15120. int set)
  15121. {
  15122. if (WXS_IS_SIMPLE(type))
  15123. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
  15124. else
  15125. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
  15126. }
  15127. /**
  15128. * xmlSchemaCheckCOSCTExtends:
  15129. * @ctxt: the schema parser context
  15130. * @type: the complex type definition
  15131. *
  15132. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15133. * Schema Component Constraint:
  15134. * Derivation Valid (Extension) (cos-ct-extends)
  15135. *
  15136. * STATUS:
  15137. * missing:
  15138. * (1.5)
  15139. * (1.4.3.2.2.2) "Particle Valid (Extension)"
  15140. *
  15141. * Returns 0 if the constraints are satisfied, a positive
  15142. * error code if not and -1 if an internal error occured.
  15143. */
  15144. static int
  15145. xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  15146. xmlSchemaTypePtr type)
  15147. {
  15148. xmlSchemaTypePtr base = type->baseType;
  15149. /*
  15150. * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
  15151. * temporarily only.
  15152. */
  15153. /*
  15154. * SPEC (1) "If the {base type definition} is a complex type definition,
  15155. * then all of the following must be true:"
  15156. */
  15157. if (WXS_IS_COMPLEX(base)) {
  15158. /*
  15159. * SPEC (1.1) "The {final} of the {base type definition} must not
  15160. * contain extension."
  15161. */
  15162. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15163. xmlSchemaPCustomErr(ctxt,
  15164. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15165. WXS_BASIC_CAST type, NULL,
  15166. "The 'final' of the base type definition "
  15167. "contains 'extension'", NULL);
  15168. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15169. }
  15170. /*
  15171. * ATTENTION: The constrains (1.2) and (1.3) are not applied,
  15172. * since they are automatically satisfied through the
  15173. * inheriting mechanism.
  15174. * Note that even if redefining components, the inheriting mechanism
  15175. * is used.
  15176. */
  15177. #if 0
  15178. /*
  15179. * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
  15180. * uses}
  15181. * of the complex type definition itself, that is, for every attribute
  15182. * use in the {attribute uses} of the {base type definition}, there
  15183. * must be an attribute use in the {attribute uses} of the complex
  15184. * type definition itself whose {attribute declaration} has the same
  15185. * {name}, {target namespace} and {type definition} as its attribute
  15186. * declaration"
  15187. */
  15188. if (base->attrUses != NULL) {
  15189. int i, j, found;
  15190. xmlSchemaAttributeUsePtr use, buse;
  15191. for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
  15192. buse = (WXS_LIST_CAST base->attrUses)->items[i];
  15193. found = 0;
  15194. if (type->attrUses != NULL) {
  15195. use = (WXS_LIST_CAST type->attrUses)->items[j];
  15196. for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
  15197. {
  15198. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15199. WXS_ATTRUSE_DECL_NAME(buse)) &&
  15200. (WXS_ATTRUSE_DECL_TNS(use) ==
  15201. WXS_ATTRUSE_DECL_TNS(buse)) &&
  15202. (WXS_ATTRUSE_TYPEDEF(use) ==
  15203. WXS_ATTRUSE_TYPEDEF(buse))
  15204. {
  15205. found = 1;
  15206. break;
  15207. }
  15208. }
  15209. }
  15210. if (! found) {
  15211. xmlChar *str = NULL;
  15212. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15213. XML_SCHEMAP_COS_CT_EXTENDS_1_2,
  15214. NULL, WXS_BASIC_CAST type,
  15215. /*
  15216. * TODO: The report does not indicate that also the
  15217. * type needs to be the same.
  15218. */
  15219. "This type is missing a matching correspondent "
  15220. "for its {base type}'s %s in its {attribute uses}",
  15221. xmlSchemaGetComponentDesignation(&str,
  15222. buse->children),
  15223. NULL);
  15224. FREE_AND_NULL(str)
  15225. }
  15226. }
  15227. }
  15228. /*
  15229. * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
  15230. * definition must also have one, and the base type definition's
  15231. * {attribute wildcard}'s {namespace constraint} must be a subset
  15232. * of the complex type definition's {attribute wildcard}'s {namespace
  15233. * constraint}, as defined by Wildcard Subset (�3.10.6)."
  15234. */
  15235. /*
  15236. * MAYBE TODO: Enable if ever needed. But this will be needed only
  15237. * if created the type via a schema construction API.
  15238. */
  15239. if (base->attributeWildcard != NULL) {
  15240. if (type->attributeWilcard == NULL) {
  15241. xmlChar *str = NULL;
  15242. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15243. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15244. NULL, type,
  15245. "The base %s has an attribute wildcard, "
  15246. "but this type is missing an attribute wildcard",
  15247. xmlSchemaGetComponentDesignation(&str, base));
  15248. FREE_AND_NULL(str)
  15249. } else if (xmlSchemaCheckCOSNSSubset(
  15250. base->attributeWildcard, type->attributeWildcard))
  15251. {
  15252. xmlChar *str = NULL;
  15253. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15254. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15255. NULL, type,
  15256. "The attribute wildcard is not a valid "
  15257. "superset of the one in the base %s",
  15258. xmlSchemaGetComponentDesignation(&str, base));
  15259. FREE_AND_NULL(str)
  15260. }
  15261. }
  15262. #endif
  15263. /*
  15264. * SPEC (1.4) "One of the following must be true:"
  15265. */
  15266. if ((type->contentTypeDef != NULL) &&
  15267. (type->contentTypeDef == base->contentTypeDef)) {
  15268. /*
  15269. * SPEC (1.4.1) "The {content type} of the {base type definition}
  15270. * and the {content type} of the complex type definition itself
  15271. * must be the same simple type definition"
  15272. * PASS
  15273. */
  15274. } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
  15275. (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
  15276. /*
  15277. * SPEC (1.4.2) "The {content type} of both the {base type
  15278. * definition} and the complex type definition itself must
  15279. * be empty."
  15280. * PASS
  15281. */
  15282. } else {
  15283. /*
  15284. * SPEC (1.4.3) "All of the following must be true:"
  15285. */
  15286. if (type->subtypes == NULL) {
  15287. /*
  15288. * SPEC 1.4.3.1 The {content type} of the complex type
  15289. * definition itself must specify a particle.
  15290. */
  15291. xmlSchemaPCustomErr(ctxt,
  15292. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15293. WXS_BASIC_CAST type, NULL,
  15294. "The content type must specify a particle", NULL);
  15295. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15296. }
  15297. /*
  15298. * SPEC (1.4.3.2) "One of the following must be true:"
  15299. */
  15300. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15301. /*
  15302. * SPEC (1.4.3.2.1) "The {content type} of the {base type
  15303. * definition} must be empty.
  15304. * PASS
  15305. */
  15306. } else {
  15307. /*
  15308. * SPEC (1.4.3.2.2) "All of the following must be true:"
  15309. */
  15310. if ((type->contentType != base->contentType) ||
  15311. ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
  15312. (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
  15313. /*
  15314. * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
  15315. * or both must be element-only."
  15316. */
  15317. xmlSchemaPCustomErr(ctxt,
  15318. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15319. WXS_BASIC_CAST type, NULL,
  15320. "The content type of both, the type and its base "
  15321. "type, must either 'mixed' or 'element-only'", NULL);
  15322. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15323. }
  15324. /*
  15325. * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
  15326. * complex type definition must be a �valid extension�
  15327. * of the {base type definition}'s particle, as defined
  15328. * in Particle Valid (Extension) (�3.9.6)."
  15329. *
  15330. * NOTE that we won't check "Particle Valid (Extension)",
  15331. * since it is ensured by the derivation process in
  15332. * xmlSchemaTypeFixup(). We need to implement this when heading
  15333. * for a construction API
  15334. * TODO: !! This is needed to be checked if redefining a type !!
  15335. */
  15336. }
  15337. /*
  15338. * URGENT TODO (1.5)
  15339. */
  15340. }
  15341. } else {
  15342. /*
  15343. * SPEC (2) "If the {base type definition} is a simple type definition,
  15344. * then all of the following must be true:"
  15345. */
  15346. if (type->contentTypeDef != base) {
  15347. /*
  15348. * SPEC (2.1) "The {content type} must be the same simple type
  15349. * definition."
  15350. */
  15351. xmlSchemaPCustomErr(ctxt,
  15352. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15353. WXS_BASIC_CAST type, NULL,
  15354. "The content type must be the simple base type", NULL);
  15355. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15356. }
  15357. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15358. /*
  15359. * SPEC (2.2) "The {final} of the {base type definition} must not
  15360. * contain extension"
  15361. * NOTE that this is the same as (1.1).
  15362. */
  15363. xmlSchemaPCustomErr(ctxt,
  15364. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15365. WXS_BASIC_CAST type, NULL,
  15366. "The 'final' of the base type definition "
  15367. "contains 'extension'", NULL);
  15368. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15369. }
  15370. }
  15371. return (0);
  15372. }
  15373. /**
  15374. * xmlSchemaCheckDerivationOKRestriction:
  15375. * @ctxt: the schema parser context
  15376. * @type: the complex type definition
  15377. *
  15378. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15379. * Schema Component Constraint:
  15380. * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
  15381. *
  15382. * STATUS:
  15383. * missing:
  15384. * (5.4.2) ???
  15385. *
  15386. * ATTENTION:
  15387. * In XML Schema 1.1 this will be:
  15388. * Validation Rule: Checking complex type subsumption
  15389. *
  15390. * Returns 0 if the constraints are satisfied, a positive
  15391. * error code if not and -1 if an internal error occured.
  15392. */
  15393. static int
  15394. xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  15395. xmlSchemaTypePtr type)
  15396. {
  15397. xmlSchemaTypePtr base;
  15398. /*
  15399. * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
  15400. * temporarily only.
  15401. */
  15402. base = type->baseType;
  15403. if (! WXS_IS_COMPLEX(base)) {
  15404. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15405. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15406. type->node, WXS_BASIC_CAST type,
  15407. "The base type must be a complex type", NULL, NULL);
  15408. return(ctxt->err);
  15409. }
  15410. if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
  15411. /*
  15412. * SPEC (1) "The {base type definition} must be a complex type
  15413. * definition whose {final} does not contain restriction."
  15414. */
  15415. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15416. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15417. type->node, WXS_BASIC_CAST type,
  15418. "The 'final' of the base type definition "
  15419. "contains 'restriction'", NULL, NULL);
  15420. return (ctxt->err);
  15421. }
  15422. /*
  15423. * SPEC (2), (3) and (4)
  15424. * Those are handled in a separate function, since the
  15425. * same constraints are needed for redefinition of
  15426. * attribute groups as well.
  15427. */
  15428. if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
  15429. XML_SCHEMA_ACTION_DERIVE,
  15430. WXS_BASIC_CAST type, WXS_BASIC_CAST base,
  15431. type->attrUses, base->attrUses,
  15432. type->attributeWildcard,
  15433. base->attributeWildcard) == -1)
  15434. {
  15435. return(-1);
  15436. }
  15437. /*
  15438. * SPEC (5) "One of the following must be true:"
  15439. */
  15440. if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
  15441. /*
  15442. * SPEC (5.1) "The {base type definition} must be the
  15443. * �ur-type definition�."
  15444. * PASS
  15445. */
  15446. } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15447. (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15448. /*
  15449. * SPEC (5.2.1) "The {content type} of the complex type definition
  15450. * must be a simple type definition"
  15451. *
  15452. * SPEC (5.2.2) "One of the following must be true:"
  15453. */
  15454. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15455. (base->contentType == XML_SCHEMA_CONTENT_BASIC))
  15456. {
  15457. int err;
  15458. /*
  15459. * SPEC (5.2.2.1) "The {content type} of the {base type
  15460. * definition} must be a simple type definition from which
  15461. * the {content type} is validly derived given the empty
  15462. * set as defined in Type Derivation OK (Simple) (�3.14.6)."
  15463. *
  15464. * ATTENTION TODO: This seems not needed if the type implicitely
  15465. * derived from the base type.
  15466. *
  15467. */
  15468. err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
  15469. type->contentTypeDef, base->contentTypeDef, 0);
  15470. if (err != 0) {
  15471. xmlChar *strA = NULL, *strB = NULL;
  15472. if (err == -1)
  15473. return(-1);
  15474. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15475. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15476. NULL, WXS_BASIC_CAST type,
  15477. "The {content type} %s is not validly derived from the "
  15478. "base type's {content type} %s",
  15479. xmlSchemaGetComponentDesignation(&strA,
  15480. type->contentTypeDef),
  15481. xmlSchemaGetComponentDesignation(&strB,
  15482. base->contentTypeDef));
  15483. FREE_AND_NULL(strA);
  15484. FREE_AND_NULL(strB);
  15485. return(ctxt->err);
  15486. }
  15487. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15488. (xmlSchemaIsParticleEmptiable(
  15489. (xmlSchemaParticlePtr) base->subtypes))) {
  15490. /*
  15491. * SPEC (5.2.2.2) "The {base type definition} must be mixed
  15492. * and have a particle which is �emptiable� as defined in
  15493. * Particle Emptiable (�3.9.6)."
  15494. * PASS
  15495. */
  15496. } else {
  15497. xmlSchemaPCustomErr(ctxt,
  15498. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15499. WXS_BASIC_CAST type, NULL,
  15500. "The content type of the base type must be either "
  15501. "a simple type or 'mixed' and an emptiable particle", NULL);
  15502. return (ctxt->err);
  15503. }
  15504. } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15505. /*
  15506. * SPEC (5.3.1) "The {content type} of the complex type itself must
  15507. * be empty"
  15508. */
  15509. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15510. /*
  15511. * SPEC (5.3.2.1) "The {content type} of the {base type
  15512. * definition} must also be empty."
  15513. * PASS
  15514. */
  15515. } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15516. (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
  15517. xmlSchemaIsParticleEmptiable(
  15518. (xmlSchemaParticlePtr) base->subtypes)) {
  15519. /*
  15520. * SPEC (5.3.2.2) "The {content type} of the {base type
  15521. * definition} must be elementOnly or mixed and have a particle
  15522. * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
  15523. * PASS
  15524. */
  15525. } else {
  15526. xmlSchemaPCustomErr(ctxt,
  15527. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15528. WXS_BASIC_CAST type, NULL,
  15529. "The content type of the base type must be either "
  15530. "empty or 'mixed' (or 'elements-only') and an emptiable "
  15531. "particle", NULL);
  15532. return (ctxt->err);
  15533. }
  15534. } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15535. WXS_HAS_MIXED_CONTENT(type)) {
  15536. /*
  15537. * SPEC (5.4.1.1) "The {content type} of the complex type definition
  15538. * itself must be element-only"
  15539. */
  15540. if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
  15541. /*
  15542. * SPEC (5.4.1.2) "The {content type} of the complex type
  15543. * definition itself and of the {base type definition} must be
  15544. * mixed"
  15545. */
  15546. xmlSchemaPCustomErr(ctxt,
  15547. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15548. WXS_BASIC_CAST type, NULL,
  15549. "If the content type is 'mixed', then the content type of the "
  15550. "base type must also be 'mixed'", NULL);
  15551. return (ctxt->err);
  15552. }
  15553. /*
  15554. * SPEC (5.4.2) "The particle of the complex type definition itself
  15555. * must be a �valid restriction� of the particle of the {content
  15556. * type} of the {base type definition} as defined in Particle Valid
  15557. * (Restriction) (�3.9.6).
  15558. *
  15559. * URGENT TODO: (5.4.2)
  15560. */
  15561. } else {
  15562. xmlSchemaPCustomErr(ctxt,
  15563. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15564. WXS_BASIC_CAST type, NULL,
  15565. "The type is not a valid restriction of its base type", NULL);
  15566. return (ctxt->err);
  15567. }
  15568. return (0);
  15569. }
  15570. /**
  15571. * xmlSchemaCheckCTComponent:
  15572. * @ctxt: the schema parser context
  15573. * @type: the complex type definition
  15574. *
  15575. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15576. *
  15577. * Returns 0 if the constraints are satisfied, a positive
  15578. * error code if not and -1 if an internal error occured.
  15579. */
  15580. static int
  15581. xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  15582. xmlSchemaTypePtr type)
  15583. {
  15584. int ret;
  15585. /*
  15586. * Complex Type Definition Properties Correct
  15587. */
  15588. ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
  15589. if (ret != 0)
  15590. return (ret);
  15591. if (WXS_IS_EXTENSION(type))
  15592. ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
  15593. else
  15594. ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
  15595. return (ret);
  15596. }
  15597. /**
  15598. * xmlSchemaCheckSRCCT:
  15599. * @ctxt: the schema parser context
  15600. * @type: the complex type definition
  15601. *
  15602. * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
  15603. * Schema Representation Constraint:
  15604. * Complex Type Definition Representation OK (src-ct)
  15605. *
  15606. * Returns 0 if the constraints are satisfied, a positive
  15607. * error code if not and -1 if an internal error occured.
  15608. */
  15609. static int
  15610. xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  15611. xmlSchemaTypePtr type)
  15612. {
  15613. xmlSchemaTypePtr base;
  15614. int ret = 0;
  15615. /*
  15616. * TODO: Adjust the error codes here, as I used
  15617. * XML_SCHEMAP_SRC_CT_1 only yet.
  15618. */
  15619. base = type->baseType;
  15620. if (! WXS_HAS_SIMPLE_CONTENT(type)) {
  15621. /*
  15622. * 1 If the <complexContent> alternative is chosen, the type definition
  15623. * �resolved� to by the �actual value� of the base [attribute]
  15624. * must be a complex type definition;
  15625. */
  15626. if (! WXS_IS_COMPLEX(base)) {
  15627. xmlChar *str = NULL;
  15628. xmlSchemaPCustomErr(ctxt,
  15629. XML_SCHEMAP_SRC_CT_1,
  15630. WXS_BASIC_CAST type, type->node,
  15631. "If using <complexContent>, the base type is expected to be "
  15632. "a complex type. The base type '%s' is a simple type",
  15633. xmlSchemaFormatQName(&str, base->targetNamespace,
  15634. base->name));
  15635. FREE_AND_NULL(str)
  15636. return (XML_SCHEMAP_SRC_CT_1);
  15637. }
  15638. } else {
  15639. /*
  15640. * SPEC
  15641. * 2 If the <simpleContent> alternative is chosen, all of the
  15642. * following must be true:
  15643. * 2.1 The type definition �resolved� to by the �actual value� of the
  15644. * base [attribute] must be one of the following:
  15645. */
  15646. if (WXS_IS_SIMPLE(base)) {
  15647. if (WXS_IS_EXTENSION(type) == 0) {
  15648. xmlChar *str = NULL;
  15649. /*
  15650. * 2.1.3 only if the <extension> alternative is also
  15651. * chosen, a simple type definition.
  15652. */
  15653. /* TODO: Change error code to ..._SRC_CT_2_1_3. */
  15654. xmlSchemaPCustomErr(ctxt,
  15655. XML_SCHEMAP_SRC_CT_1,
  15656. WXS_BASIC_CAST type, NULL,
  15657. "If using <simpleContent> and <restriction>, the base "
  15658. "type must be a complex type. The base type '%s' is "
  15659. "a simple type",
  15660. xmlSchemaFormatQName(&str, base->targetNamespace,
  15661. base->name));
  15662. FREE_AND_NULL(str)
  15663. return (XML_SCHEMAP_SRC_CT_1);
  15664. }
  15665. } else {
  15666. /* Base type is a complex type. */
  15667. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15668. (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15669. /*
  15670. * 2.1.1 a complex type definition whose {content type} is a
  15671. * simple type definition;
  15672. * PASS
  15673. */
  15674. if (base->contentTypeDef == NULL) {
  15675. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
  15676. WXS_BASIC_CAST type, NULL,
  15677. "Internal error: xmlSchemaCheckSRCCT, "
  15678. "'%s', base type has no content type",
  15679. type->name);
  15680. return (-1);
  15681. }
  15682. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15683. (WXS_IS_RESTRICTION(type))) {
  15684. /*
  15685. * 2.1.2 only if the <restriction> alternative is also
  15686. * chosen, a complex type definition whose {content type}
  15687. * is mixed and a particle emptiable.
  15688. */
  15689. if (! xmlSchemaIsParticleEmptiable(
  15690. (xmlSchemaParticlePtr) base->subtypes)) {
  15691. ret = XML_SCHEMAP_SRC_CT_1;
  15692. } else
  15693. /*
  15694. * Attention: at this point the <simpleType> child is in
  15695. * ->contentTypeDef (put there during parsing).
  15696. */
  15697. if (type->contentTypeDef == NULL) {
  15698. xmlChar *str = NULL;
  15699. /*
  15700. * 2.2 If clause 2.1.2 above is satisfied, then there
  15701. * must be a <simpleType> among the [children] of
  15702. * <restriction>.
  15703. */
  15704. /* TODO: Change error code to ..._SRC_CT_2_2. */
  15705. xmlSchemaPCustomErr(ctxt,
  15706. XML_SCHEMAP_SRC_CT_1,
  15707. WXS_BASIC_CAST type, NULL,
  15708. "A <simpleType> is expected among the children "
  15709. "of <restriction>, if <simpleContent> is used and "
  15710. "the base type '%s' is a complex type",
  15711. xmlSchemaFormatQName(&str, base->targetNamespace,
  15712. base->name));
  15713. FREE_AND_NULL(str)
  15714. return (XML_SCHEMAP_SRC_CT_1);
  15715. }
  15716. } else {
  15717. ret = XML_SCHEMAP_SRC_CT_1;
  15718. }
  15719. }
  15720. if (ret > 0) {
  15721. xmlChar *str = NULL;
  15722. if (WXS_IS_RESTRICTION(type)) {
  15723. xmlSchemaPCustomErr(ctxt,
  15724. XML_SCHEMAP_SRC_CT_1,
  15725. WXS_BASIC_CAST type, NULL,
  15726. "If <simpleContent> and <restriction> is used, the "
  15727. "base type must be a simple type or a complex type with "
  15728. "mixed content and particle emptiable. The base type "
  15729. "'%s' is none of those",
  15730. xmlSchemaFormatQName(&str, base->targetNamespace,
  15731. base->name));
  15732. } else {
  15733. xmlSchemaPCustomErr(ctxt,
  15734. XML_SCHEMAP_SRC_CT_1,
  15735. WXS_BASIC_CAST type, NULL,
  15736. "If <simpleContent> and <extension> is used, the "
  15737. "base type must be a simple type. The base type '%s' "
  15738. "is a complex type",
  15739. xmlSchemaFormatQName(&str, base->targetNamespace,
  15740. base->name));
  15741. }
  15742. FREE_AND_NULL(str)
  15743. }
  15744. }
  15745. /*
  15746. * SPEC (3) "The corresponding complex type definition component must
  15747. * satisfy the conditions set out in Constraints on Complex Type
  15748. * Definition Schema Components (�3.4.6);"
  15749. * NOTE (3) will be done in xmlSchemaTypeFixup().
  15750. */
  15751. /*
  15752. * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
  15753. * above for {attribute wildcard} is satisfied, the intensional
  15754. * intersection must be expressible, as defined in Attribute Wildcard
  15755. * Intersection (�3.10.6).
  15756. * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
  15757. */
  15758. return (ret);
  15759. }
  15760. #ifdef ENABLE_PARTICLE_RESTRICTION
  15761. /**
  15762. * xmlSchemaCheckParticleRangeOK:
  15763. * @ctxt: the schema parser context
  15764. * @type: the complex type definition
  15765. *
  15766. * (3.9.6) Constraints on Particle Schema Components
  15767. * Schema Component Constraint:
  15768. * Occurrence Range OK (range-ok)
  15769. *
  15770. * STATUS: complete
  15771. *
  15772. * Returns 0 if the constraints are satisfied, a positive
  15773. * error code if not and -1 if an internal error occured.
  15774. */
  15775. static int
  15776. xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  15777. int bmin, int bmax)
  15778. {
  15779. if (rmin < bmin)
  15780. return (1);
  15781. if ((bmax != UNBOUNDED) &&
  15782. (rmax > bmax))
  15783. return (1);
  15784. return (0);
  15785. }
  15786. /**
  15787. * xmlSchemaCheckRCaseNameAndTypeOK:
  15788. * @ctxt: the schema parser context
  15789. * @r: the restricting element declaration particle
  15790. * @b: the base element declaration particle
  15791. *
  15792. * (3.9.6) Constraints on Particle Schema Components
  15793. * Schema Component Constraint:
  15794. * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
  15795. * (rcase-NameAndTypeOK)
  15796. *
  15797. * STATUS:
  15798. * MISSING (3.2.3)
  15799. * CLARIFY: (3.2.2)
  15800. *
  15801. * Returns 0 if the constraints are satisfied, a positive
  15802. * error code if not and -1 if an internal error occured.
  15803. */
  15804. static int
  15805. xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  15806. xmlSchemaParticlePtr r,
  15807. xmlSchemaParticlePtr b)
  15808. {
  15809. xmlSchemaElementPtr elemR, elemB;
  15810. /* TODO: Error codes (rcase-NameAndTypeOK). */
  15811. elemR = (xmlSchemaElementPtr) r->children;
  15812. elemB = (xmlSchemaElementPtr) b->children;
  15813. /*
  15814. * SPEC (1) "The declarations' {name}s and {target namespace}s are
  15815. * the same."
  15816. */
  15817. if ((elemR != elemB) &&
  15818. ((! xmlStrEqual(elemR->name, elemB->name)) ||
  15819. (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
  15820. return (1);
  15821. /*
  15822. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15823. * occurrence range as defined by Occurrence Range OK (�3.9.6)."
  15824. */
  15825. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15826. b->minOccurs, b->maxOccurs) != 0)
  15827. return (1);
  15828. /*
  15829. * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
  15830. * {scope} are global."
  15831. */
  15832. if (elemR == elemB)
  15833. return (0);
  15834. /*
  15835. * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
  15836. */
  15837. if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
  15838. (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
  15839. return (1);
  15840. /*
  15841. * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
  15842. * or is not fixed, or R's declaration's {value constraint} is fixed
  15843. * with the same value."
  15844. */
  15845. if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
  15846. ((elemR->value == NULL) ||
  15847. ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
  15848. /* TODO: Equality of the initial value or normalized or canonical? */
  15849. (! xmlStrEqual(elemR->value, elemB->value))))
  15850. return (1);
  15851. /*
  15852. * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
  15853. * definitions} is a subset of B's declaration's {identity-constraint
  15854. * definitions}, if any."
  15855. */
  15856. if (elemB->idcs != NULL) {
  15857. /* TODO */
  15858. }
  15859. /*
  15860. * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
  15861. * superset of B's declaration's {disallowed substitutions}."
  15862. */
  15863. if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
  15864. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
  15865. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
  15866. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
  15867. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
  15868. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
  15869. return (1);
  15870. /*
  15871. * SPEC (3.2.5) "R's {type definition} is validly derived given
  15872. * {extension, list, union} from B's {type definition}"
  15873. *
  15874. * BADSPEC TODO: What's the point of adding "list" and "union" to the
  15875. * set, if the corresponding constraints handle "restriction" and
  15876. * "extension" only?
  15877. *
  15878. */
  15879. {
  15880. int set = 0;
  15881. set |= SUBSET_EXTENSION;
  15882. set |= SUBSET_LIST;
  15883. set |= SUBSET_UNION;
  15884. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
  15885. elemB->subtypes, set) != 0)
  15886. return (1);
  15887. }
  15888. return (0);
  15889. }
  15890. /**
  15891. * xmlSchemaCheckRCaseNSCompat:
  15892. * @ctxt: the schema parser context
  15893. * @r: the restricting element declaration particle
  15894. * @b: the base wildcard particle
  15895. *
  15896. * (3.9.6) Constraints on Particle Schema Components
  15897. * Schema Component Constraint:
  15898. * Particle Derivation OK (Elt:Any -- NSCompat)
  15899. * (rcase-NSCompat)
  15900. *
  15901. * STATUS: complete
  15902. *
  15903. * Returns 0 if the constraints are satisfied, a positive
  15904. * error code if not and -1 if an internal error occured.
  15905. */
  15906. static int
  15907. xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  15908. xmlSchemaParticlePtr r,
  15909. xmlSchemaParticlePtr b)
  15910. {
  15911. /* TODO:Error codes (rcase-NSCompat). */
  15912. /*
  15913. * SPEC "For an element declaration particle to be a �valid restriction�
  15914. * of a wildcard particle all of the following must be true:"
  15915. *
  15916. * SPEC (1) "The element declaration's {target namespace} is �valid�
  15917. * with respect to the wildcard's {namespace constraint} as defined by
  15918. * Wildcard allows Namespace Name (�3.10.4)."
  15919. */
  15920. if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
  15921. ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
  15922. return (1);
  15923. /*
  15924. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15925. * occurrence range as defined by Occurrence Range OK (�3.9.6)."
  15926. */
  15927. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15928. b->minOccurs, b->maxOccurs) != 0)
  15929. return (1);
  15930. return (0);
  15931. }
  15932. /**
  15933. * xmlSchemaCheckRCaseRecurseAsIfGroup:
  15934. * @ctxt: the schema parser context
  15935. * @r: the restricting element declaration particle
  15936. * @b: the base model group particle
  15937. *
  15938. * (3.9.6) Constraints on Particle Schema Components
  15939. * Schema Component Constraint:
  15940. * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
  15941. * (rcase-RecurseAsIfGroup)
  15942. *
  15943. * STATUS: TODO
  15944. *
  15945. * Returns 0 if the constraints are satisfied, a positive
  15946. * error code if not and -1 if an internal error occured.
  15947. */
  15948. static int
  15949. xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  15950. xmlSchemaParticlePtr r,
  15951. xmlSchemaParticlePtr b)
  15952. {
  15953. /* TODO: Error codes (rcase-RecurseAsIfGroup). */
  15954. TODO
  15955. return (0);
  15956. }
  15957. /**
  15958. * xmlSchemaCheckRCaseNSSubset:
  15959. * @ctxt: the schema parser context
  15960. * @r: the restricting wildcard particle
  15961. * @b: the base wildcard particle
  15962. *
  15963. * (3.9.6) Constraints on Particle Schema Components
  15964. * Schema Component Constraint:
  15965. * Particle Derivation OK (Any:Any -- NSSubset)
  15966. * (rcase-NSSubset)
  15967. *
  15968. * STATUS: complete
  15969. *
  15970. * Returns 0 if the constraints are satisfied, a positive
  15971. * error code if not and -1 if an internal error occured.
  15972. */
  15973. static int
  15974. xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  15975. xmlSchemaParticlePtr r,
  15976. xmlSchemaParticlePtr b,
  15977. int isAnyTypeBase)
  15978. {
  15979. /* TODO: Error codes (rcase-NSSubset). */
  15980. /*
  15981. * SPEC (1) "R's occurrence range is a valid restriction of B's
  15982. * occurrence range as defined by Occurrence Range OK (�3.9.6)."
  15983. */
  15984. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15985. b->minOccurs, b->maxOccurs))
  15986. return (1);
  15987. /*
  15988. * SPEC (2) "R's {namespace constraint} must be an intensional subset
  15989. * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
  15990. */
  15991. if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
  15992. (xmlSchemaWildcardPtr) b->children))
  15993. return (1);
  15994. /*
  15995. * SPEC (3) "Unless B is the content model wildcard of the �ur-type
  15996. * definition�, R's {process contents} must be identical to or stronger
  15997. * than B's {process contents}, where strict is stronger than lax is
  15998. * stronger than skip."
  15999. */
  16000. if (! isAnyTypeBase) {
  16001. if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
  16002. ((xmlSchemaWildcardPtr) b->children)->processContents)
  16003. return (1);
  16004. }
  16005. return (0);
  16006. }
  16007. /**
  16008. * xmlSchemaCheckCOSParticleRestrict:
  16009. * @ctxt: the schema parser context
  16010. * @type: the complex type definition
  16011. *
  16012. * (3.9.6) Constraints on Particle Schema Components
  16013. * Schema Component Constraint:
  16014. * Particle Valid (Restriction) (cos-particle-restrict)
  16015. *
  16016. * STATUS: TODO
  16017. *
  16018. * Returns 0 if the constraints are satisfied, a positive
  16019. * error code if not and -1 if an internal error occured.
  16020. */
  16021. static int
  16022. xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  16023. xmlSchemaParticlePtr r,
  16024. xmlSchemaParticlePtr b)
  16025. {
  16026. int ret = 0;
  16027. /*part = WXS_TYPE_PARTICLE(type);
  16028. basePart = WXS_TYPE_PARTICLE(base);
  16029. */
  16030. TODO
  16031. /*
  16032. * SPEC (1) "They are the same particle."
  16033. */
  16034. if (r == b)
  16035. return (0);
  16036. return (0);
  16037. }
  16038. #if 0
  16039. /**
  16040. * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
  16041. * @ctxt: the schema parser context
  16042. * @r: the model group particle
  16043. * @b: the base wildcard particle
  16044. *
  16045. * (3.9.6) Constraints on Particle Schema Components
  16046. * Schema Component Constraint:
  16047. * Particle Derivation OK (All/Choice/Sequence:Any --
  16048. * NSRecurseCheckCardinality)
  16049. * (rcase-NSRecurseCheckCardinality)
  16050. *
  16051. * STATUS: TODO: subst-groups
  16052. *
  16053. * Returns 0 if the constraints are satisfied, a positive
  16054. * error code if not and -1 if an internal error occured.
  16055. */
  16056. static int
  16057. xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  16058. xmlSchemaParticlePtr r,
  16059. xmlSchemaParticlePtr b)
  16060. {
  16061. xmlSchemaParticlePtr part;
  16062. /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
  16063. if ((r->children == NULL) || (r->children->children == NULL))
  16064. return (-1);
  16065. /*
  16066. * SPEC "For a group particle to be a �valid restriction� of a
  16067. * wildcard particle..."
  16068. *
  16069. * SPEC (1) "Every member of the {particles} of the group is a �valid
  16070. * restriction� of the wildcard as defined by
  16071. * Particle Valid (Restriction) (�3.9.6)."
  16072. */
  16073. part = (xmlSchemaParticlePtr) r->children->children;
  16074. do {
  16075. if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
  16076. return (1);
  16077. part = (xmlSchemaParticlePtr) part->next;
  16078. } while (part != NULL);
  16079. /*
  16080. * SPEC (2) "The effective total range of the group [...] is a
  16081. * valid restriction of B's occurrence range as defined by
  16082. * Occurrence Range OK (�3.9.6)."
  16083. */
  16084. if (xmlSchemaCheckParticleRangeOK(
  16085. xmlSchemaGetParticleTotalRangeMin(r),
  16086. xmlSchemaGetParticleTotalRangeMax(r),
  16087. b->minOccurs, b->maxOccurs) != 0)
  16088. return (1);
  16089. return (0);
  16090. }
  16091. #endif
  16092. /**
  16093. * xmlSchemaCheckRCaseRecurse:
  16094. * @ctxt: the schema parser context
  16095. * @r: the <all> or <sequence> model group particle
  16096. * @b: the base <all> or <sequence> model group particle
  16097. *
  16098. * (3.9.6) Constraints on Particle Schema Components
  16099. * Schema Component Constraint:
  16100. * Particle Derivation OK (All:All,Sequence:Sequence --
  16101. Recurse)
  16102. * (rcase-Recurse)
  16103. *
  16104. * STATUS: ?
  16105. * TODO: subst-groups
  16106. *
  16107. * Returns 0 if the constraints are satisfied, a positive
  16108. * error code if not and -1 if an internal error occured.
  16109. */
  16110. static int
  16111. xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
  16112. xmlSchemaParticlePtr r,
  16113. xmlSchemaParticlePtr b)
  16114. {
  16115. /* xmlSchemaParticlePtr part; */
  16116. /* TODO: Error codes (rcase-Recurse). */
  16117. if ((r->children == NULL) || (b->children == NULL) ||
  16118. (r->children->type != b->children->type))
  16119. return (-1);
  16120. /*
  16121. * SPEC "For an all or sequence group particle to be a �valid
  16122. * restriction� of another group particle with the same {compositor}..."
  16123. *
  16124. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16125. * occurrence range as defined by Occurrence Range OK (�3.9.6)."
  16126. */
  16127. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16128. b->minOccurs, b->maxOccurs))
  16129. return (1);
  16130. return (0);
  16131. }
  16132. #endif
  16133. #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
  16134. xmlSchemaPCustomErrExt(pctxt, \
  16135. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16136. WXS_BASIC_CAST fac1, fac1->node, \
  16137. "It is an error for both '%s' and '%s' to be specified on the "\
  16138. "same type definition", \
  16139. BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
  16140. BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
  16141. #define FACET_RESTR_ERR(fac1, msg) \
  16142. xmlSchemaPCustomErr(pctxt, \
  16143. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16144. WXS_BASIC_CAST fac1, fac1->node, \
  16145. msg, NULL);
  16146. #define FACET_RESTR_FIXED_ERR(fac) \
  16147. xmlSchemaPCustomErr(pctxt, \
  16148. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16149. WXS_BASIC_CAST fac, fac->node, \
  16150. "The base type's facet is 'fixed', thus the value must not " \
  16151. "differ", NULL);
  16152. static void
  16153. xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
  16154. xmlSchemaFacetPtr facet1,
  16155. xmlSchemaFacetPtr facet2,
  16156. int lessGreater,
  16157. int orEqual,
  16158. int ofBase)
  16159. {
  16160. xmlChar *msg = NULL;
  16161. msg = xmlStrdup(BAD_CAST "'");
  16162. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
  16163. msg = xmlStrcat(msg, BAD_CAST "' has to be");
  16164. if (lessGreater == 0)
  16165. msg = xmlStrcat(msg, BAD_CAST " equal to");
  16166. if (lessGreater == 1)
  16167. msg = xmlStrcat(msg, BAD_CAST " greater than");
  16168. else
  16169. msg = xmlStrcat(msg, BAD_CAST " less than");
  16170. if (orEqual)
  16171. msg = xmlStrcat(msg, BAD_CAST " or equal to");
  16172. msg = xmlStrcat(msg, BAD_CAST " '");
  16173. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
  16174. if (ofBase)
  16175. msg = xmlStrcat(msg, BAD_CAST "' of the base type");
  16176. else
  16177. msg = xmlStrcat(msg, BAD_CAST "'");
  16178. xmlSchemaPCustomErr(pctxt,
  16179. XML_SCHEMAP_INVALID_FACET_VALUE,
  16180. WXS_BASIC_CAST facet1, NULL,
  16181. (const char *) msg, NULL);
  16182. if (msg != NULL)
  16183. xmlFree(msg);
  16184. }
  16185. /*
  16186. * xmlSchemaDeriveAndValidateFacets:
  16187. *
  16188. * Schema Component Constraint: Simple Type Restriction (Facets)
  16189. * (st-restrict-facets)
  16190. */
  16191. static int
  16192. xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
  16193. xmlSchemaTypePtr type)
  16194. {
  16195. xmlSchemaTypePtr base = type->baseType;
  16196. xmlSchemaFacetLinkPtr link, cur, last = NULL;
  16197. xmlSchemaFacetPtr facet, bfacet,
  16198. flength = NULL, ftotdig = NULL, ffracdig = NULL,
  16199. fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
  16200. fmininc = NULL, fmaxinc = NULL,
  16201. fminexc = NULL, fmaxexc = NULL,
  16202. bflength = NULL, bftotdig = NULL, bffracdig = NULL,
  16203. bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
  16204. bfmininc = NULL, bfmaxinc = NULL,
  16205. bfminexc = NULL, bfmaxexc = NULL;
  16206. int res; /* err = 0, fixedErr; */
  16207. /*
  16208. * SPEC st-restrict-facets 1:
  16209. * "The {variety} of R is the same as that of B."
  16210. */
  16211. /*
  16212. * SPEC st-restrict-facets 2:
  16213. * "If {variety} is atomic, the {primitive type definition}
  16214. * of R is the same as that of B."
  16215. *
  16216. * NOTE: we leave 1 & 2 out for now, since this will be
  16217. * satisfied by the derivation process.
  16218. * CONSTRUCTION TODO: Maybe needed if using a construction API.
  16219. */
  16220. /*
  16221. * SPEC st-restrict-facets 3:
  16222. * "The {facets} of R are the union of S and the {facets}
  16223. * of B, eliminating duplicates. To eliminate duplicates,
  16224. * when a facet of the same kind occurs in both S and the
  16225. * {facets} of B, the one in the {facets} of B is not
  16226. * included, with the exception of enumeration and pattern
  16227. * facets, for which multiple occurrences with distinct values
  16228. * are allowed."
  16229. */
  16230. if ((type->facetSet == NULL) && (base->facetSet == NULL))
  16231. return (0);
  16232. last = type->facetSet;
  16233. if (last != NULL)
  16234. while (last->next != NULL)
  16235. last = last->next;
  16236. for (cur = type->facetSet; cur != NULL; cur = cur->next) {
  16237. facet = cur->facet;
  16238. switch (facet->type) {
  16239. case XML_SCHEMA_FACET_LENGTH:
  16240. flength = facet; break;
  16241. case XML_SCHEMA_FACET_MINLENGTH:
  16242. fminlen = facet; break;
  16243. case XML_SCHEMA_FACET_MININCLUSIVE:
  16244. fmininc = facet; break;
  16245. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16246. fminexc = facet; break;
  16247. case XML_SCHEMA_FACET_MAXLENGTH:
  16248. fmaxlen = facet; break;
  16249. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16250. fmaxinc = facet; break;
  16251. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16252. fmaxexc = facet; break;
  16253. case XML_SCHEMA_FACET_TOTALDIGITS:
  16254. ftotdig = facet; break;
  16255. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16256. ffracdig = facet; break;
  16257. default:
  16258. break;
  16259. }
  16260. }
  16261. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16262. facet = cur->facet;
  16263. switch (facet->type) {
  16264. case XML_SCHEMA_FACET_LENGTH:
  16265. bflength = facet; break;
  16266. case XML_SCHEMA_FACET_MINLENGTH:
  16267. bfminlen = facet; break;
  16268. case XML_SCHEMA_FACET_MININCLUSIVE:
  16269. bfmininc = facet; break;
  16270. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16271. bfminexc = facet; break;
  16272. case XML_SCHEMA_FACET_MAXLENGTH:
  16273. bfmaxlen = facet; break;
  16274. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16275. bfmaxinc = facet; break;
  16276. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16277. bfmaxexc = facet; break;
  16278. case XML_SCHEMA_FACET_TOTALDIGITS:
  16279. bftotdig = facet; break;
  16280. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16281. bffracdig = facet; break;
  16282. default:
  16283. break;
  16284. }
  16285. }
  16286. /*
  16287. * length and minLength or maxLength (2.2) + (3.2)
  16288. */
  16289. if (flength && (fminlen || fmaxlen)) {
  16290. FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
  16291. "either of 'minLength' or 'maxLength' to be specified on "
  16292. "the same type definition")
  16293. }
  16294. /*
  16295. * Mutual exclusions in the same derivation step.
  16296. */
  16297. if ((fmaxinc) && (fmaxexc)) {
  16298. /*
  16299. * SCC "maxInclusive and maxExclusive"
  16300. */
  16301. FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
  16302. }
  16303. if ((fmininc) && (fminexc)) {
  16304. /*
  16305. * SCC "minInclusive and minExclusive"
  16306. */
  16307. FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
  16308. }
  16309. if (flength && bflength) {
  16310. /*
  16311. * SCC "length valid restriction"
  16312. * The values have to be equal.
  16313. */
  16314. res = xmlSchemaCompareValues(flength->val, bflength->val);
  16315. if (res == -2)
  16316. goto internal_error;
  16317. if (res != 0)
  16318. xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
  16319. if ((res != 0) && (bflength->fixed)) {
  16320. FACET_RESTR_FIXED_ERR(flength)
  16321. }
  16322. }
  16323. if (fminlen && bfminlen) {
  16324. /*
  16325. * SCC "minLength valid restriction"
  16326. * minLength >= BASE minLength
  16327. */
  16328. res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
  16329. if (res == -2)
  16330. goto internal_error;
  16331. if (res == -1)
  16332. xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
  16333. if ((res != 0) && (bfminlen->fixed)) {
  16334. FACET_RESTR_FIXED_ERR(fminlen)
  16335. }
  16336. }
  16337. if (fmaxlen && bfmaxlen) {
  16338. /*
  16339. * SCC "maxLength valid restriction"
  16340. * maxLength <= BASE minLength
  16341. */
  16342. res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
  16343. if (res == -2)
  16344. goto internal_error;
  16345. if (res == 1)
  16346. xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
  16347. if ((res != 0) && (bfmaxlen->fixed)) {
  16348. FACET_RESTR_FIXED_ERR(fmaxlen)
  16349. }
  16350. }
  16351. /*
  16352. * SCC "length and minLength or maxLength"
  16353. */
  16354. if (! flength)
  16355. flength = bflength;
  16356. if (flength) {
  16357. if (! fminlen)
  16358. fminlen = bfminlen;
  16359. if (fminlen) {
  16360. /* (1.1) length >= minLength */
  16361. res = xmlSchemaCompareValues(flength->val, fminlen->val);
  16362. if (res == -2)
  16363. goto internal_error;
  16364. if (res == -1)
  16365. xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
  16366. }
  16367. if (! fmaxlen)
  16368. fmaxlen = bfmaxlen;
  16369. if (fmaxlen) {
  16370. /* (2.1) length <= maxLength */
  16371. res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
  16372. if (res == -2)
  16373. goto internal_error;
  16374. if (res == 1)
  16375. xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
  16376. }
  16377. }
  16378. if (fmaxinc) {
  16379. /*
  16380. * "maxInclusive"
  16381. */
  16382. if (fmininc) {
  16383. /* SCC "maxInclusive >= minInclusive" */
  16384. res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
  16385. if (res == -2)
  16386. goto internal_error;
  16387. if (res == -1) {
  16388. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
  16389. }
  16390. }
  16391. /*
  16392. * SCC "maxInclusive valid restriction"
  16393. */
  16394. if (bfmaxinc) {
  16395. /* maxInclusive <= BASE maxInclusive */
  16396. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
  16397. if (res == -2)
  16398. goto internal_error;
  16399. if (res == 1)
  16400. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
  16401. if ((res != 0) && (bfmaxinc->fixed)) {
  16402. FACET_RESTR_FIXED_ERR(fmaxinc)
  16403. }
  16404. }
  16405. if (bfmaxexc) {
  16406. /* maxInclusive < BASE maxExclusive */
  16407. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
  16408. if (res == -2)
  16409. goto internal_error;
  16410. if (res != -1) {
  16411. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
  16412. }
  16413. }
  16414. if (bfmininc) {
  16415. /* maxInclusive >= BASE minInclusive */
  16416. res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
  16417. if (res == -2)
  16418. goto internal_error;
  16419. if (res == -1) {
  16420. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
  16421. }
  16422. }
  16423. if (bfminexc) {
  16424. /* maxInclusive > BASE minExclusive */
  16425. res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
  16426. if (res == -2)
  16427. goto internal_error;
  16428. if (res != 1) {
  16429. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
  16430. }
  16431. }
  16432. }
  16433. if (fmaxexc) {
  16434. /*
  16435. * "maxExclusive >= minExclusive"
  16436. */
  16437. if (fminexc) {
  16438. res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
  16439. if (res == -2)
  16440. goto internal_error;
  16441. if (res == -1) {
  16442. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
  16443. }
  16444. }
  16445. /*
  16446. * "maxExclusive valid restriction"
  16447. */
  16448. if (bfmaxexc) {
  16449. /* maxExclusive <= BASE maxExclusive */
  16450. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
  16451. if (res == -2)
  16452. goto internal_error;
  16453. if (res == 1) {
  16454. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
  16455. }
  16456. if ((res != 0) && (bfmaxexc->fixed)) {
  16457. FACET_RESTR_FIXED_ERR(fmaxexc)
  16458. }
  16459. }
  16460. if (bfmaxinc) {
  16461. /* maxExclusive <= BASE maxInclusive */
  16462. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
  16463. if (res == -2)
  16464. goto internal_error;
  16465. if (res == 1) {
  16466. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
  16467. }
  16468. }
  16469. if (bfmininc) {
  16470. /* maxExclusive > BASE minInclusive */
  16471. res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
  16472. if (res == -2)
  16473. goto internal_error;
  16474. if (res != 1) {
  16475. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
  16476. }
  16477. }
  16478. if (bfminexc) {
  16479. /* maxExclusive > BASE minExclusive */
  16480. res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
  16481. if (res == -2)
  16482. goto internal_error;
  16483. if (res != 1) {
  16484. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
  16485. }
  16486. }
  16487. }
  16488. if (fminexc) {
  16489. /*
  16490. * "minExclusive < maxInclusive"
  16491. */
  16492. if (fmaxinc) {
  16493. res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
  16494. if (res == -2)
  16495. goto internal_error;
  16496. if (res != -1) {
  16497. xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
  16498. }
  16499. }
  16500. /*
  16501. * "minExclusive valid restriction"
  16502. */
  16503. if (bfminexc) {
  16504. /* minExclusive >= BASE minExclusive */
  16505. res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
  16506. if (res == -2)
  16507. goto internal_error;
  16508. if (res == -1) {
  16509. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
  16510. }
  16511. if ((res != 0) && (bfminexc->fixed)) {
  16512. FACET_RESTR_FIXED_ERR(fminexc)
  16513. }
  16514. }
  16515. if (bfmaxinc) {
  16516. /* minExclusive <= BASE maxInclusive */
  16517. res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
  16518. if (res == -2)
  16519. goto internal_error;
  16520. if (res == 1) {
  16521. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
  16522. }
  16523. }
  16524. if (bfmininc) {
  16525. /* minExclusive >= BASE minInclusive */
  16526. res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
  16527. if (res == -2)
  16528. goto internal_error;
  16529. if (res == -1) {
  16530. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
  16531. }
  16532. }
  16533. if (bfmaxexc) {
  16534. /* minExclusive < BASE maxExclusive */
  16535. res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
  16536. if (res == -2)
  16537. goto internal_error;
  16538. if (res != -1) {
  16539. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
  16540. }
  16541. }
  16542. }
  16543. if (fmininc) {
  16544. /*
  16545. * "minInclusive < maxExclusive"
  16546. */
  16547. if (fmaxexc) {
  16548. res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
  16549. if (res == -2)
  16550. goto internal_error;
  16551. if (res != -1) {
  16552. xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
  16553. }
  16554. }
  16555. /*
  16556. * "minExclusive valid restriction"
  16557. */
  16558. if (bfmininc) {
  16559. /* minInclusive >= BASE minInclusive */
  16560. res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
  16561. if (res == -2)
  16562. goto internal_error;
  16563. if (res == -1) {
  16564. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
  16565. }
  16566. if ((res != 0) && (bfmininc->fixed)) {
  16567. FACET_RESTR_FIXED_ERR(fmininc)
  16568. }
  16569. }
  16570. if (bfmaxinc) {
  16571. /* minInclusive <= BASE maxInclusive */
  16572. res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
  16573. if (res == -2)
  16574. goto internal_error;
  16575. if (res == 1) {
  16576. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
  16577. }
  16578. }
  16579. if (bfminexc) {
  16580. /* minInclusive > BASE minExclusive */
  16581. res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
  16582. if (res == -2)
  16583. goto internal_error;
  16584. if (res != 1)
  16585. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
  16586. }
  16587. if (bfmaxexc) {
  16588. /* minInclusive < BASE maxExclusive */
  16589. res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
  16590. if (res == -2)
  16591. goto internal_error;
  16592. if (res != -1)
  16593. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
  16594. }
  16595. }
  16596. if (ftotdig && bftotdig) {
  16597. /*
  16598. * SCC " totalDigits valid restriction"
  16599. * totalDigits <= BASE totalDigits
  16600. */
  16601. res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
  16602. if (res == -2)
  16603. goto internal_error;
  16604. if (res == 1)
  16605. xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
  16606. -1, 1, 1);
  16607. if ((res != 0) && (bftotdig->fixed)) {
  16608. FACET_RESTR_FIXED_ERR(ftotdig)
  16609. }
  16610. }
  16611. if (ffracdig && bffracdig) {
  16612. /*
  16613. * SCC "fractionDigits valid restriction"
  16614. * fractionDigits <= BASE fractionDigits
  16615. */
  16616. res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
  16617. if (res == -2)
  16618. goto internal_error;
  16619. if (res == 1)
  16620. xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
  16621. -1, 1, 1);
  16622. if ((res != 0) && (bffracdig->fixed)) {
  16623. FACET_RESTR_FIXED_ERR(ffracdig)
  16624. }
  16625. }
  16626. /*
  16627. * SCC "fractionDigits less than or equal to totalDigits"
  16628. */
  16629. if (! ftotdig)
  16630. ftotdig = bftotdig;
  16631. if (! ffracdig)
  16632. ffracdig = bffracdig;
  16633. if (ftotdig && ffracdig) {
  16634. res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
  16635. if (res == -2)
  16636. goto internal_error;
  16637. if (res == 1)
  16638. xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
  16639. -1, 1, 0);
  16640. }
  16641. /*
  16642. * *Enumerations* won' be added here, since only the first set
  16643. * of enumerations in the ancestor-or-self axis is used
  16644. * for validation, plus we need to use the base type of those
  16645. * enumerations for whitespace.
  16646. *
  16647. * *Patterns*: won't be add here, since they are ORed at
  16648. * type level and ANDed at ancestor level. This will
  16649. * happed during validation by walking the base axis
  16650. * of the type.
  16651. */
  16652. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16653. bfacet = cur->facet;
  16654. /*
  16655. * Special handling of enumerations and patterns.
  16656. * TODO: hmm, they should not appear in the set, so remove this.
  16657. */
  16658. if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
  16659. (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
  16660. continue;
  16661. /*
  16662. * Search for a duplicate facet in the current type.
  16663. */
  16664. link = type->facetSet;
  16665. /* err = 0; */
  16666. /* fixedErr = 0; */
  16667. while (link != NULL) {
  16668. facet = link->facet;
  16669. if (facet->type == bfacet->type) {
  16670. switch (facet->type) {
  16671. case XML_SCHEMA_FACET_WHITESPACE:
  16672. /*
  16673. * The whitespace must be stronger.
  16674. */
  16675. if (facet->whitespace < bfacet->whitespace) {
  16676. FACET_RESTR_ERR(facet,
  16677. "The 'whitespace' value has to be equal to "
  16678. "or stronger than the 'whitespace' value of "
  16679. "the base type")
  16680. }
  16681. if ((bfacet->fixed) &&
  16682. (facet->whitespace != bfacet->whitespace)) {
  16683. FACET_RESTR_FIXED_ERR(facet)
  16684. }
  16685. break;
  16686. default:
  16687. break;
  16688. }
  16689. /* Duplicate found. */
  16690. break;
  16691. }
  16692. link = link->next;
  16693. }
  16694. /*
  16695. * If no duplicate was found: add the base types's facet
  16696. * to the set.
  16697. */
  16698. if (link == NULL) {
  16699. link = (xmlSchemaFacetLinkPtr)
  16700. xmlMalloc(sizeof(xmlSchemaFacetLink));
  16701. if (link == NULL) {
  16702. xmlSchemaPErrMemory(pctxt,
  16703. "deriving facets, creating a facet link", NULL);
  16704. return (-1);
  16705. }
  16706. link->facet = cur->facet;
  16707. link->next = NULL;
  16708. if (last == NULL)
  16709. type->facetSet = link;
  16710. else
  16711. last->next = link;
  16712. last = link;
  16713. }
  16714. }
  16715. return (0);
  16716. internal_error:
  16717. PERROR_INT("xmlSchemaDeriveAndValidateFacets",
  16718. "an error occured");
  16719. return (-1);
  16720. }
  16721. static int
  16722. xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
  16723. xmlSchemaTypePtr type)
  16724. {
  16725. xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
  16726. /*
  16727. * The actual value is then formed by replacing any union type
  16728. * definition in the �explicit members� with the members of their
  16729. * {member type definitions}, in order.
  16730. *
  16731. * TODO: There's a bug entry at
  16732. * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
  16733. * which indicates that we'll keep the union types the future.
  16734. */
  16735. link = type->memberTypes;
  16736. while (link != NULL) {
  16737. if (WXS_IS_TYPE_NOT_FIXED(link->type))
  16738. xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
  16739. if (WXS_IS_UNION(link->type)) {
  16740. subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
  16741. if (subLink != NULL) {
  16742. link->type = subLink->type;
  16743. if (subLink->next != NULL) {
  16744. lastLink = link->next;
  16745. subLink = subLink->next;
  16746. prevLink = link;
  16747. while (subLink != NULL) {
  16748. newLink = (xmlSchemaTypeLinkPtr)
  16749. xmlMalloc(sizeof(xmlSchemaTypeLink));
  16750. if (newLink == NULL) {
  16751. xmlSchemaPErrMemory(pctxt, "allocating a type link",
  16752. NULL);
  16753. return (-1);
  16754. }
  16755. newLink->type = subLink->type;
  16756. prevLink->next = newLink;
  16757. prevLink = newLink;
  16758. newLink->next = lastLink;
  16759. subLink = subLink->next;
  16760. }
  16761. }
  16762. }
  16763. }
  16764. link = link->next;
  16765. }
  16766. return (0);
  16767. }
  16768. static void
  16769. xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
  16770. {
  16771. int has = 0, needVal = 0, normVal = 0;
  16772. has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
  16773. if (has) {
  16774. needVal = (type->baseType->flags &
  16775. XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
  16776. normVal = (type->baseType->flags &
  16777. XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
  16778. }
  16779. if (type->facets != NULL) {
  16780. xmlSchemaFacetPtr fac;
  16781. for (fac = type->facets; fac != NULL; fac = fac->next) {
  16782. switch (fac->type) {
  16783. case XML_SCHEMA_FACET_WHITESPACE:
  16784. break;
  16785. case XML_SCHEMA_FACET_PATTERN:
  16786. normVal = 1;
  16787. has = 1;
  16788. break;
  16789. case XML_SCHEMA_FACET_ENUMERATION:
  16790. needVal = 1;
  16791. normVal = 1;
  16792. has = 1;
  16793. break;
  16794. default:
  16795. has = 1;
  16796. break;
  16797. }
  16798. }
  16799. }
  16800. if (normVal)
  16801. type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
  16802. if (needVal)
  16803. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16804. if (has)
  16805. type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
  16806. if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
  16807. xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
  16808. /*
  16809. * OPTIMIZE VAL TODO: Some facets need a computed value.
  16810. */
  16811. if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
  16812. (prim->builtInType != XML_SCHEMAS_STRING)) {
  16813. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16814. }
  16815. }
  16816. }
  16817. static int
  16818. xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
  16819. {
  16820. /*
  16821. * Evaluate the whitespace-facet value.
  16822. */
  16823. if (WXS_IS_LIST(type)) {
  16824. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16825. return (0);
  16826. } else if (WXS_IS_UNION(type))
  16827. return (0);
  16828. if (type->facetSet != NULL) {
  16829. xmlSchemaFacetLinkPtr lin;
  16830. for (lin = type->facetSet; lin != NULL; lin = lin->next) {
  16831. if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
  16832. switch (lin->facet->whitespace) {
  16833. case XML_SCHEMAS_FACET_PRESERVE:
  16834. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16835. break;
  16836. case XML_SCHEMAS_FACET_REPLACE:
  16837. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16838. break;
  16839. case XML_SCHEMAS_FACET_COLLAPSE:
  16840. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16841. break;
  16842. default:
  16843. return (-1);
  16844. }
  16845. return (0);
  16846. }
  16847. }
  16848. }
  16849. /*
  16850. * For all �atomic� datatypes other than string (and types �derived�
  16851. * by �restriction� from it) the value of whiteSpace is fixed to
  16852. * collapse
  16853. */
  16854. {
  16855. xmlSchemaTypePtr anc;
  16856. for (anc = type->baseType; anc != NULL &&
  16857. anc->builtInType != XML_SCHEMAS_ANYTYPE;
  16858. anc = anc->baseType) {
  16859. if (anc->type == XML_SCHEMA_TYPE_BASIC) {
  16860. if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
  16861. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16862. } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
  16863. (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
  16864. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16865. } else
  16866. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16867. break;
  16868. }
  16869. }
  16870. }
  16871. return (0);
  16872. }
  16873. static int
  16874. xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
  16875. xmlSchemaTypePtr type)
  16876. {
  16877. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  16878. return(0);
  16879. if (! WXS_IS_TYPE_NOT_FIXED_1(type))
  16880. return(0);
  16881. type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
  16882. if (WXS_IS_LIST(type)) {
  16883. /*
  16884. * Corresponds to <simpleType><list>...
  16885. */
  16886. if (type->subtypes == NULL) {
  16887. /*
  16888. * This one is really needed, so get out.
  16889. */
  16890. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16891. "list type has no item-type assigned");
  16892. return(-1);
  16893. }
  16894. } else if (WXS_IS_UNION(type)) {
  16895. /*
  16896. * Corresponds to <simpleType><union>...
  16897. */
  16898. if (type->memberTypes == NULL) {
  16899. /*
  16900. * This one is really needed, so get out.
  16901. */
  16902. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16903. "union type has no member-types assigned");
  16904. return(-1);
  16905. }
  16906. } else {
  16907. /*
  16908. * Corresponds to <simpleType><restriction>...
  16909. */
  16910. if (type->baseType == NULL) {
  16911. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16912. "type has no base-type assigned");
  16913. return(-1);
  16914. }
  16915. if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
  16916. if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
  16917. return(-1);
  16918. /*
  16919. * Variety
  16920. * If the <restriction> alternative is chosen, then the
  16921. * {variety} of the {base type definition}.
  16922. */
  16923. if (WXS_IS_ATOMIC(type->baseType))
  16924. type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
  16925. else if (WXS_IS_LIST(type->baseType)) {
  16926. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  16927. /*
  16928. * Inherit the itemType.
  16929. */
  16930. type->subtypes = type->baseType->subtypes;
  16931. } else if (WXS_IS_UNION(type->baseType)) {
  16932. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  16933. /*
  16934. * NOTE that we won't assign the memberTypes of the base,
  16935. * since this will make trouble when freeing them; we will
  16936. * use a lookup function to access them instead.
  16937. */
  16938. }
  16939. }
  16940. return(0);
  16941. }
  16942. #ifdef DEBUG_TYPE
  16943. static void
  16944. xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
  16945. xmlSchemaTypePtr type)
  16946. {
  16947. if (type->node != NULL) {
  16948. xmlGenericError(xmlGenericErrorContext,
  16949. "Type of %s : %s:%d :", name,
  16950. type->node->doc->URL,
  16951. xmlGetLineNo(type->node));
  16952. } else {
  16953. xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
  16954. }
  16955. if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
  16956. switch (type->contentType) {
  16957. case XML_SCHEMA_CONTENT_SIMPLE:
  16958. xmlGenericError(xmlGenericErrorContext, "simple\n");
  16959. break;
  16960. case XML_SCHEMA_CONTENT_ELEMENTS:
  16961. xmlGenericError(xmlGenericErrorContext, "elements\n");
  16962. break;
  16963. case XML_SCHEMA_CONTENT_UNKNOWN:
  16964. xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
  16965. break;
  16966. case XML_SCHEMA_CONTENT_EMPTY:
  16967. xmlGenericError(xmlGenericErrorContext, "empty\n");
  16968. break;
  16969. case XML_SCHEMA_CONTENT_MIXED:
  16970. if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
  16971. type->subtypes))
  16972. xmlGenericError(xmlGenericErrorContext,
  16973. "mixed as emptiable particle\n");
  16974. else
  16975. xmlGenericError(xmlGenericErrorContext, "mixed\n");
  16976. break;
  16977. /* Removed, since not used. */
  16978. /*
  16979. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  16980. xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
  16981. break;
  16982. */
  16983. case XML_SCHEMA_CONTENT_BASIC:
  16984. xmlGenericError(xmlGenericErrorContext, "basic\n");
  16985. break;
  16986. default:
  16987. xmlGenericError(xmlGenericErrorContext,
  16988. "not registered !!!\n");
  16989. break;
  16990. }
  16991. }
  16992. }
  16993. #endif
  16994. /*
  16995. * 3.14.6 Constraints on Simple Type Definition Schema Components
  16996. */
  16997. static int
  16998. xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
  16999. xmlSchemaTypePtr type)
  17000. {
  17001. int res, olderrs = pctxt->nberrors;
  17002. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17003. return(-1);
  17004. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17005. return(0);
  17006. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17007. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  17008. if (type->baseType == NULL) {
  17009. PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
  17010. "missing baseType");
  17011. goto exit_failure;
  17012. }
  17013. if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
  17014. xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
  17015. /*
  17016. * If a member type of a union is a union itself, we need to substitute
  17017. * that member type for its member types.
  17018. * NOTE that this might change in WXS 1.1; i.e. we will keep the union
  17019. * types in WXS 1.1.
  17020. */
  17021. if ((type->memberTypes != NULL) &&
  17022. (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
  17023. return(-1);
  17024. /*
  17025. * SPEC src-simple-type 1
  17026. * "The corresponding simple type definition, if any, must satisfy
  17027. * the conditions set out in Constraints on Simple Type Definition
  17028. * Schema Components (�3.14.6)."
  17029. */
  17030. /*
  17031. * Schema Component Constraint: Simple Type Definition Properties Correct
  17032. * (st-props-correct)
  17033. */
  17034. res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
  17035. HFAILURE HERROR
  17036. /*
  17037. * Schema Component Constraint: Derivation Valid (Restriction, Simple)
  17038. * (cos-st-restricts)
  17039. */
  17040. res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
  17041. HFAILURE HERROR
  17042. /*
  17043. * TODO: Removed the error report, since it got annoying to get an
  17044. * extra error report, if anything failed until now.
  17045. * Enable this if needed.
  17046. *
  17047. * xmlSchemaPErr(ctxt, type->node,
  17048. * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  17049. * "Simple type '%s' does not satisfy the constraints "
  17050. * "on simple type definitions.\n",
  17051. * type->name, NULL);
  17052. */
  17053. /*
  17054. * Schema Component Constraint: Simple Type Restriction (Facets)
  17055. * (st-restrict-facets)
  17056. */
  17057. res = xmlSchemaCheckFacetValues(type, pctxt);
  17058. HFAILURE HERROR
  17059. if ((type->facetSet != NULL) ||
  17060. (type->baseType->facetSet != NULL)) {
  17061. res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
  17062. HFAILURE HERROR
  17063. }
  17064. /*
  17065. * Whitespace value.
  17066. */
  17067. res = xmlSchemaTypeFixupWhitespace(type);
  17068. HFAILURE HERROR
  17069. xmlSchemaTypeFixupOptimFacets(type);
  17070. exit_error:
  17071. #ifdef DEBUG_TYPE
  17072. xmlSchemaDebugFixedType(pctxt, type);
  17073. #endif
  17074. if (olderrs != pctxt->nberrors)
  17075. return(pctxt->err);
  17076. return(0);
  17077. exit_failure:
  17078. #ifdef DEBUG_TYPE
  17079. xmlSchemaDebugFixedType(pctxt, type);
  17080. #endif
  17081. return(-1);
  17082. }
  17083. static int
  17084. xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
  17085. xmlSchemaTypePtr type)
  17086. {
  17087. int res = 0, olderrs = pctxt->nberrors;
  17088. xmlSchemaTypePtr baseType = type->baseType;
  17089. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17090. return(0);
  17091. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17092. if (baseType == NULL) {
  17093. PERROR_INT("xmlSchemaFixupComplexType",
  17094. "missing baseType");
  17095. goto exit_failure;
  17096. }
  17097. /*
  17098. * Fixup the base type.
  17099. */
  17100. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  17101. xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
  17102. if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
  17103. /*
  17104. * Skip fixup if the base type is invalid.
  17105. * TODO: Generate a warning!
  17106. */
  17107. return(0);
  17108. }
  17109. /*
  17110. * This basically checks if the base type can be derived.
  17111. */
  17112. res = xmlSchemaCheckSRCCT(pctxt, type);
  17113. HFAILURE HERROR
  17114. /*
  17115. * Fixup the content type.
  17116. */
  17117. if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
  17118. /*
  17119. * Corresponds to <complexType><simpleContent>...
  17120. */
  17121. if ((WXS_IS_COMPLEX(baseType)) &&
  17122. (baseType->contentTypeDef != NULL) &&
  17123. (WXS_IS_RESTRICTION(type))) {
  17124. xmlSchemaTypePtr contentBase, content;
  17125. #ifdef ENABLE_NAMED_LOCALS
  17126. char buf[30];
  17127. const xmlChar *tmpname;
  17128. #endif
  17129. /*
  17130. * SPEC (1) If <restriction> + base type is <complexType>,
  17131. * "whose own {content type} is a simple type..."
  17132. */
  17133. if (type->contentTypeDef != NULL) {
  17134. /*
  17135. * SPEC (1.1) "the simple type definition corresponding to the
  17136. * <simpleType> among the [children] of <restriction> if there
  17137. * is one;"
  17138. * Note that this "<simpleType> among the [children]" was put
  17139. * into ->contentTypeDef during parsing.
  17140. */
  17141. contentBase = type->contentTypeDef;
  17142. type->contentTypeDef = NULL;
  17143. } else {
  17144. /*
  17145. * (1.2) "...otherwise (<restriction> has no <simpleType>
  17146. * among its [children]), the simple type definition which
  17147. * is the {content type} of the ... base type."
  17148. */
  17149. contentBase = baseType->contentTypeDef;
  17150. }
  17151. /*
  17152. * SPEC
  17153. * "... a simple type definition which restricts the simple
  17154. * type definition identified in clause 1.1 or clause 1.2
  17155. * with a set of facet components"
  17156. *
  17157. * Create the anonymous simple type, which will be the content
  17158. * type of the complex type.
  17159. */
  17160. #ifdef ENABLE_NAMED_LOCALS
  17161. snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
  17162. tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
  17163. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17164. XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
  17165. type->node, 0);
  17166. #else
  17167. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17168. XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
  17169. type->node, 0);
  17170. #endif
  17171. if (content == NULL)
  17172. goto exit_failure;
  17173. /*
  17174. * We will use the same node as for the <complexType>
  17175. * to have it somehow anchored in the schema doc.
  17176. */
  17177. content->type = XML_SCHEMA_TYPE_SIMPLE;
  17178. content->baseType = contentBase;
  17179. /*
  17180. * Move the facets, previously anchored on the
  17181. * complexType during parsing.
  17182. */
  17183. content->facets = type->facets;
  17184. type->facets = NULL;
  17185. content->facetSet = type->facetSet;
  17186. type->facetSet = NULL;
  17187. type->contentTypeDef = content;
  17188. if (WXS_IS_TYPE_NOT_FIXED(contentBase))
  17189. xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
  17190. /*
  17191. * Fixup the newly created type. We don't need to check
  17192. * for circularity here.
  17193. */
  17194. res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
  17195. HFAILURE HERROR
  17196. res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
  17197. HFAILURE HERROR
  17198. } else if ((WXS_IS_COMPLEX(baseType)) &&
  17199. (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  17200. (WXS_IS_RESTRICTION(type))) {
  17201. /*
  17202. * SPEC (2) If <restriction> + base is a mixed <complexType> with
  17203. * an emptiable particle, then a simple type definition which
  17204. * restricts the <restriction>'s <simpleType> child.
  17205. */
  17206. if ((type->contentTypeDef == NULL) ||
  17207. (type->contentTypeDef->baseType == NULL)) {
  17208. /*
  17209. * TODO: Check if this ever happens.
  17210. */
  17211. xmlSchemaPCustomErr(pctxt,
  17212. XML_SCHEMAP_INTERNAL,
  17213. WXS_BASIC_CAST type, NULL,
  17214. "Internal error: xmlSchemaTypeFixup, "
  17215. "complex type '%s': the <simpleContent><restriction> "
  17216. "is missing a <simpleType> child, but was not catched "
  17217. "by xmlSchemaCheckSRCCT()", type->name);
  17218. goto exit_failure;
  17219. }
  17220. } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
  17221. /*
  17222. * SPEC (3) If <extension> + base is <complexType> with
  17223. * <simpleType> content, "...then the {content type} of that
  17224. * complex type definition"
  17225. */
  17226. if (baseType->contentTypeDef == NULL) {
  17227. /*
  17228. * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
  17229. * should have catched this already.
  17230. */
  17231. xmlSchemaPCustomErr(pctxt,
  17232. XML_SCHEMAP_INTERNAL,
  17233. WXS_BASIC_CAST type, NULL,
  17234. "Internal error: xmlSchemaTypeFixup, "
  17235. "complex type '%s': the <extension>ed base type is "
  17236. "a complex type with no simple content type",
  17237. type->name);
  17238. goto exit_failure;
  17239. }
  17240. type->contentTypeDef = baseType->contentTypeDef;
  17241. } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
  17242. /*
  17243. * SPEC (4) <extension> + base is <simpleType>
  17244. * "... then that simple type definition"
  17245. */
  17246. type->contentTypeDef = baseType;
  17247. } else {
  17248. /*
  17249. * TODO: Check if this ever happens.
  17250. */
  17251. xmlSchemaPCustomErr(pctxt,
  17252. XML_SCHEMAP_INTERNAL,
  17253. WXS_BASIC_CAST type, NULL,
  17254. "Internal error: xmlSchemaTypeFixup, "
  17255. "complex type '%s' with <simpleContent>: unhandled "
  17256. "derivation case", type->name);
  17257. goto exit_failure;
  17258. }
  17259. } else {
  17260. int dummySequence = 0;
  17261. xmlSchemaParticlePtr particle =
  17262. (xmlSchemaParticlePtr) type->subtypes;
  17263. /*
  17264. * Corresponds to <complexType><complexContent>...
  17265. *
  17266. * NOTE that the effective mixed was already set during parsing of
  17267. * <complexType> and <complexContent>; its flag value is
  17268. * XML_SCHEMAS_TYPE_MIXED.
  17269. *
  17270. * Compute the "effective content":
  17271. * (2.1.1) + (2.1.2) + (2.1.3)
  17272. */
  17273. if ((particle == NULL) ||
  17274. ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
  17275. ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
  17276. (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  17277. ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
  17278. (particle->minOccurs == 0))) &&
  17279. ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
  17280. if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
  17281. /*
  17282. * SPEC (2.1.4) "If the �effective mixed� is true, then
  17283. * a particle whose properties are as follows:..."
  17284. *
  17285. * Empty sequence model group with
  17286. * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
  17287. * NOTE that we sill assign it the <complexType> node to
  17288. * somehow anchor it in the doc.
  17289. */
  17290. if ((particle == NULL) ||
  17291. (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
  17292. /*
  17293. * Create the particle.
  17294. */
  17295. particle = xmlSchemaAddParticle(pctxt,
  17296. type->node, 1, 1);
  17297. if (particle == NULL)
  17298. goto exit_failure;
  17299. /*
  17300. * Create the model group.
  17301. */ /* URGENT TODO: avoid adding to pending items. */
  17302. particle->children = (xmlSchemaTreeItemPtr)
  17303. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17304. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17305. if (particle->children == NULL)
  17306. goto exit_failure;
  17307. type->subtypes = (xmlSchemaTypePtr) particle;
  17308. }
  17309. dummySequence = 1;
  17310. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17311. } else {
  17312. /*
  17313. * SPEC (2.1.5) "otherwise empty"
  17314. */
  17315. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  17316. }
  17317. } else {
  17318. /*
  17319. * SPEC (2.2) "otherwise the particle corresponding to the
  17320. * <all>, <choice>, <group> or <sequence> among the
  17321. * [children]."
  17322. */
  17323. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17324. }
  17325. /*
  17326. * Compute the "content type".
  17327. */
  17328. if (WXS_IS_RESTRICTION(type)) {
  17329. /*
  17330. * SPEC (3.1) "If <restriction>..."
  17331. * (3.1.1) + (3.1.2) */
  17332. if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
  17333. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17334. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17335. }
  17336. } else {
  17337. /*
  17338. * SPEC (3.2) "If <extension>..."
  17339. */
  17340. if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17341. /*
  17342. * SPEC (3.2.1)
  17343. * "If the �effective content� is empty, then the
  17344. * {content type} of the [...] base ..."
  17345. */
  17346. type->contentType = baseType->contentType;
  17347. type->subtypes = baseType->subtypes;
  17348. /*
  17349. * Fixes bug #347316:
  17350. * This is the case when the base type has a simple
  17351. * type definition as content.
  17352. */
  17353. type->contentTypeDef = baseType->contentTypeDef;
  17354. /*
  17355. * NOTE that the effective mixed is ignored here.
  17356. */
  17357. } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17358. /*
  17359. * SPEC (3.2.2)
  17360. */
  17361. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17362. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17363. } else {
  17364. /*
  17365. * SPEC (3.2.3)
  17366. */
  17367. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17368. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17369. /*
  17370. * "A model group whose {compositor} is sequence and whose
  17371. * {particles} are..."
  17372. */
  17373. if ((WXS_TYPE_PARTICLE(type) != NULL) &&
  17374. (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
  17375. ((WXS_TYPE_PARTICLE_TERM(type))->type ==
  17376. XML_SCHEMA_TYPE_ALL))
  17377. {
  17378. /*
  17379. * SPEC cos-all-limited (1)
  17380. */
  17381. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17382. /* TODO: error code */
  17383. XML_SCHEMAP_COS_ALL_LIMITED,
  17384. WXS_ITEM_NODE(type), NULL,
  17385. "The type has an 'all' model group in its "
  17386. "{content type} and thus cannot be derived from "
  17387. "a non-empty type, since this would produce a "
  17388. "'sequence' model group containing the 'all' "
  17389. "model group; 'all' model groups are not "
  17390. "allowed to appear inside other model groups",
  17391. NULL, NULL);
  17392. } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
  17393. (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
  17394. ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
  17395. XML_SCHEMA_TYPE_ALL))
  17396. {
  17397. /*
  17398. * SPEC cos-all-limited (1)
  17399. */
  17400. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17401. /* TODO: error code */
  17402. XML_SCHEMAP_COS_ALL_LIMITED,
  17403. WXS_ITEM_NODE(type), NULL,
  17404. "A type cannot be derived by extension from a type "
  17405. "which has an 'all' model group in its "
  17406. "{content type}, since this would produce a "
  17407. "'sequence' model group containing the 'all' "
  17408. "model group; 'all' model groups are not "
  17409. "allowed to appear inside other model groups",
  17410. NULL, NULL);
  17411. } else if (! dummySequence) {
  17412. xmlSchemaTreeItemPtr effectiveContent =
  17413. (xmlSchemaTreeItemPtr) type->subtypes;
  17414. /*
  17415. * Create the particle.
  17416. */
  17417. particle = xmlSchemaAddParticle(pctxt,
  17418. type->node, 1, 1);
  17419. if (particle == NULL)
  17420. goto exit_failure;
  17421. /*
  17422. * Create the "sequence" model group.
  17423. */
  17424. particle->children = (xmlSchemaTreeItemPtr)
  17425. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17426. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17427. if (particle->children == NULL)
  17428. goto exit_failure;
  17429. WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
  17430. /*
  17431. * SPEC "the particle of the {content type} of
  17432. * the ... base ..."
  17433. * Create a duplicate of the base type's particle
  17434. * and assign its "term" to it.
  17435. */
  17436. particle->children->children =
  17437. (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
  17438. type->node,
  17439. ((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
  17440. ((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
  17441. if (particle->children->children == NULL)
  17442. goto exit_failure;
  17443. particle = (xmlSchemaParticlePtr)
  17444. particle->children->children;
  17445. particle->children =
  17446. ((xmlSchemaParticlePtr) baseType->subtypes)->children;
  17447. /*
  17448. * SPEC "followed by the �effective content�."
  17449. */
  17450. particle->next = effectiveContent;
  17451. /*
  17452. * This all will result in:
  17453. * new-particle
  17454. * --> new-sequence(
  17455. * new-particle
  17456. * --> base-model,
  17457. * this-particle
  17458. * --> this-model
  17459. * )
  17460. */
  17461. } else {
  17462. /*
  17463. * This is the case when there is already an empty
  17464. * <sequence> with minOccurs==maxOccurs==1.
  17465. * Just add the base types's content type.
  17466. * NOTE that, although we miss to add an intermediate
  17467. * <sequence>, this should produce no difference to
  17468. * neither the regex compilation of the content model,
  17469. * nor to the complex type contraints.
  17470. */
  17471. particle->children->children =
  17472. (xmlSchemaTreeItemPtr) baseType->subtypes;
  17473. }
  17474. }
  17475. }
  17476. }
  17477. /*
  17478. * Now fixup attribute uses:
  17479. * - expand attr. group references
  17480. * - intersect attribute wildcards
  17481. * - inherit attribute uses of the base type
  17482. * - inherit or union attr. wildcards if extending
  17483. * - apply attr. use prohibitions if restricting
  17484. */
  17485. res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
  17486. HFAILURE HERROR
  17487. /*
  17488. * Apply the complex type component constraints; this will not
  17489. * check attributes, since this is done in
  17490. * xmlSchemaFixupTypeAttributeUses().
  17491. */
  17492. res = xmlSchemaCheckCTComponent(pctxt, type);
  17493. HFAILURE HERROR
  17494. #ifdef DEBUG_TYPE
  17495. xmlSchemaDebugFixedType(pctxt, type);
  17496. #endif
  17497. if (olderrs != pctxt->nberrors)
  17498. return(pctxt->err);
  17499. else
  17500. return(0);
  17501. exit_error:
  17502. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17503. #ifdef DEBUG_TYPE
  17504. xmlSchemaDebugFixedType(pctxt, type);
  17505. #endif
  17506. return(pctxt->err);
  17507. exit_failure:
  17508. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17509. #ifdef DEBUG_TYPE
  17510. xmlSchemaDebugFixedType(pctxt, type);
  17511. #endif
  17512. return(-1);
  17513. }
  17514. /**
  17515. * xmlSchemaTypeFixup:
  17516. * @typeDecl: the schema type definition
  17517. * @ctxt: the schema parser context
  17518. *
  17519. * Fixes the content model of the type.
  17520. * URGENT TODO: We need an int result!
  17521. */
  17522. static int
  17523. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  17524. xmlSchemaAbstractCtxtPtr actxt)
  17525. {
  17526. if (type == NULL)
  17527. return(0);
  17528. if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
  17529. AERROR_INT("xmlSchemaTypeFixup",
  17530. "this function needs a parser context");
  17531. return(-1);
  17532. }
  17533. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17534. return(0);
  17535. if (type->type == XML_SCHEMA_TYPE_COMPLEX)
  17536. return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
  17537. else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
  17538. return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
  17539. return(0);
  17540. }
  17541. /**
  17542. * xmlSchemaCheckFacet:
  17543. * @facet: the facet
  17544. * @typeDecl: the schema type definition
  17545. * @pctxt: the schema parser context or NULL
  17546. * @name: the optional name of the type
  17547. *
  17548. * Checks and computes the values of facets.
  17549. *
  17550. * Returns 0 if valid, a positive error code if not valid and
  17551. * -1 in case of an internal or API error.
  17552. */
  17553. int
  17554. xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
  17555. xmlSchemaTypePtr typeDecl,
  17556. xmlSchemaParserCtxtPtr pctxt,
  17557. const xmlChar * name ATTRIBUTE_UNUSED)
  17558. {
  17559. int ret = 0, ctxtGiven;
  17560. if ((facet == NULL) || (typeDecl == NULL))
  17561. return(-1);
  17562. /*
  17563. * TODO: will the parser context be given if used from
  17564. * the relaxNG module?
  17565. */
  17566. if (pctxt == NULL)
  17567. ctxtGiven = 0;
  17568. else
  17569. ctxtGiven = 1;
  17570. switch (facet->type) {
  17571. case XML_SCHEMA_FACET_MININCLUSIVE:
  17572. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  17573. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  17574. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  17575. case XML_SCHEMA_FACET_ENUMERATION: {
  17576. /*
  17577. * Okay we need to validate the value
  17578. * at that point.
  17579. */
  17580. xmlSchemaTypePtr base;
  17581. /* 4.3.5.5 Constraints on enumeration Schema Components
  17582. * Schema Component Constraint: enumeration valid restriction
  17583. * It is an �error� if any member of {value} is not in the
  17584. * �value space� of {base type definition}.
  17585. *
  17586. * minInclusive, maxInclusive, minExclusive, maxExclusive:
  17587. * The value �must� be in the
  17588. * �value space� of the �base type�.
  17589. */
  17590. /*
  17591. * This function is intended to deliver a compiled value
  17592. * on the facet. In this implementation of XML Schemata the
  17593. * type holding a facet, won't be a built-in type.
  17594. * Thus to ensure that other API
  17595. * calls (relaxng) do work, if the given type is a built-in
  17596. * type, we will assume that the given built-in type *is
  17597. * already* the base type.
  17598. */
  17599. if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
  17600. base = typeDecl->baseType;
  17601. if (base == NULL) {
  17602. PERROR_INT("xmlSchemaCheckFacet",
  17603. "a type user derived type has no base type");
  17604. return (-1);
  17605. }
  17606. } else
  17607. base = typeDecl;
  17608. if (! ctxtGiven) {
  17609. /*
  17610. * A context is needed if called from RelaxNG.
  17611. */
  17612. pctxt = xmlSchemaNewParserCtxt("*");
  17613. if (pctxt == NULL)
  17614. return (-1);
  17615. }
  17616. /*
  17617. * NOTE: This call does not check the content nodes,
  17618. * since they are not available:
  17619. * facet->node is just the node holding the facet
  17620. * definition, *not* the attribute holding the *value*
  17621. * of the facet.
  17622. */
  17623. ret = xmlSchemaVCheckCVCSimpleType(
  17624. ACTXT_CAST pctxt, facet->node, base,
  17625. facet->value, &(facet->val), 1, 1, 0);
  17626. if (ret != 0) {
  17627. if (ret < 0) {
  17628. /* No error message for RelaxNG. */
  17629. if (ctxtGiven) {
  17630. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17631. XML_SCHEMAP_INTERNAL, facet->node, NULL,
  17632. "Internal error: xmlSchemaCheckFacet, "
  17633. "failed to validate the value '%s' of the "
  17634. "facet '%s' against the base type",
  17635. facet->value, xmlSchemaFacetTypeToString(facet->type));
  17636. }
  17637. goto internal_error;
  17638. }
  17639. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17640. /* No error message for RelaxNG. */
  17641. if (ctxtGiven) {
  17642. xmlChar *str = NULL;
  17643. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17644. ret, facet->node, WXS_BASIC_CAST facet,
  17645. "The value '%s' of the facet does not validate "
  17646. "against the base type '%s'",
  17647. facet->value,
  17648. xmlSchemaFormatQName(&str,
  17649. base->targetNamespace, base->name));
  17650. FREE_AND_NULL(str);
  17651. }
  17652. goto exit;
  17653. } else if (facet->val == NULL) {
  17654. if (ctxtGiven) {
  17655. PERROR_INT("xmlSchemaCheckFacet",
  17656. "value was not computed");
  17657. }
  17658. TODO
  17659. }
  17660. break;
  17661. }
  17662. case XML_SCHEMA_FACET_PATTERN:
  17663. facet->regexp = xmlRegexpCompile(facet->value);
  17664. if (facet->regexp == NULL) {
  17665. ret = XML_SCHEMAP_REGEXP_INVALID;
  17666. /* No error message for RelaxNG. */
  17667. if (ctxtGiven) {
  17668. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17669. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17670. "The value '%s' of the facet 'pattern' is not a "
  17671. "valid regular expression",
  17672. facet->value, NULL);
  17673. }
  17674. }
  17675. break;
  17676. case XML_SCHEMA_FACET_TOTALDIGITS:
  17677. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  17678. case XML_SCHEMA_FACET_LENGTH:
  17679. case XML_SCHEMA_FACET_MAXLENGTH:
  17680. case XML_SCHEMA_FACET_MINLENGTH:
  17681. if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
  17682. ret = xmlSchemaValidatePredefinedType(
  17683. xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
  17684. facet->value, &(facet->val));
  17685. } else {
  17686. ret = xmlSchemaValidatePredefinedType(
  17687. xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
  17688. facet->value, &(facet->val));
  17689. }
  17690. if (ret != 0) {
  17691. if (ret < 0) {
  17692. /* No error message for RelaxNG. */
  17693. if (ctxtGiven) {
  17694. PERROR_INT("xmlSchemaCheckFacet",
  17695. "validating facet value");
  17696. }
  17697. goto internal_error;
  17698. }
  17699. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17700. /* No error message for RelaxNG. */
  17701. if (ctxtGiven) {
  17702. /* error code */
  17703. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  17704. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17705. "The value '%s' of the facet '%s' is not a valid '%s'",
  17706. facet->value,
  17707. xmlSchemaFacetTypeToString(facet->type),
  17708. (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
  17709. BAD_CAST "nonNegativeInteger" :
  17710. BAD_CAST "positiveInteger",
  17711. NULL);
  17712. }
  17713. }
  17714. break;
  17715. case XML_SCHEMA_FACET_WHITESPACE:{
  17716. if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
  17717. facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
  17718. } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
  17719. facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
  17720. } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
  17721. facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
  17722. } else {
  17723. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17724. /* No error message for RelaxNG. */
  17725. if (ctxtGiven) {
  17726. /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
  17727. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17728. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17729. "The value '%s' of the facet 'whitespace' is not "
  17730. "valid", facet->value, NULL);
  17731. }
  17732. }
  17733. }
  17734. default:
  17735. break;
  17736. }
  17737. exit:
  17738. if ((! ctxtGiven) && (pctxt != NULL))
  17739. xmlSchemaFreeParserCtxt(pctxt);
  17740. return (ret);
  17741. internal_error:
  17742. if ((! ctxtGiven) && (pctxt != NULL))
  17743. xmlSchemaFreeParserCtxt(pctxt);
  17744. return (-1);
  17745. }
  17746. /**
  17747. * xmlSchemaCheckFacetValues:
  17748. * @typeDecl: the schema type definition
  17749. * @ctxt: the schema parser context
  17750. *
  17751. * Checks the default values types, especially for facets
  17752. */
  17753. static int
  17754. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  17755. xmlSchemaParserCtxtPtr pctxt)
  17756. {
  17757. int res, olderrs = pctxt->nberrors;
  17758. const xmlChar *name = typeDecl->name;
  17759. /*
  17760. * NOTE: It is intended to use the facets list, instead
  17761. * of facetSet.
  17762. */
  17763. if (typeDecl->facets != NULL) {
  17764. xmlSchemaFacetPtr facet = typeDecl->facets;
  17765. /*
  17766. * Temporarily assign the "schema" to the validation context
  17767. * of the parser context. This is needed for NOTATION validation.
  17768. */
  17769. if (pctxt->vctxt == NULL) {
  17770. if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
  17771. return(-1);
  17772. }
  17773. pctxt->vctxt->schema = pctxt->schema;
  17774. while (facet != NULL) {
  17775. res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
  17776. HFAILURE
  17777. facet = facet->next;
  17778. }
  17779. pctxt->vctxt->schema = NULL;
  17780. }
  17781. if (olderrs != pctxt->nberrors)
  17782. return(pctxt->err);
  17783. return(0);
  17784. exit_failure:
  17785. return(-1);
  17786. }
  17787. /**
  17788. * xmlSchemaGetCircModelGrDefRef:
  17789. * @ctxtMGroup: the searched model group
  17790. * @selfMGroup: the second searched model group
  17791. * @particle: the first particle
  17792. *
  17793. * This one is intended to be used by
  17794. * xmlSchemaCheckGroupDefCircular only.
  17795. *
  17796. * Returns the particle with the circular model group definition reference,
  17797. * otherwise NULL.
  17798. */
  17799. static xmlSchemaTreeItemPtr
  17800. xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
  17801. xmlSchemaTreeItemPtr particle)
  17802. {
  17803. xmlSchemaTreeItemPtr circ = NULL;
  17804. xmlSchemaTreeItemPtr term;
  17805. xmlSchemaModelGroupDefPtr gdef;
  17806. for (; particle != NULL; particle = particle->next) {
  17807. term = particle->children;
  17808. if (term == NULL)
  17809. continue;
  17810. switch (term->type) {
  17811. case XML_SCHEMA_TYPE_GROUP:
  17812. gdef = (xmlSchemaModelGroupDefPtr) term;
  17813. if (gdef == groupDef)
  17814. return (particle);
  17815. /*
  17816. * Mark this model group definition to avoid infinite
  17817. * recursion on circular references not yet examined.
  17818. */
  17819. if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
  17820. continue;
  17821. if (gdef->children != NULL) {
  17822. gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17823. circ = xmlSchemaGetCircModelGrDefRef(groupDef,
  17824. gdef->children->children);
  17825. gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17826. if (circ != NULL)
  17827. return (circ);
  17828. }
  17829. break;
  17830. case XML_SCHEMA_TYPE_SEQUENCE:
  17831. case XML_SCHEMA_TYPE_CHOICE:
  17832. case XML_SCHEMA_TYPE_ALL:
  17833. circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
  17834. if (circ != NULL)
  17835. return (circ);
  17836. break;
  17837. default:
  17838. break;
  17839. }
  17840. }
  17841. return (NULL);
  17842. }
  17843. /**
  17844. * xmlSchemaCheckGroupDefCircular:
  17845. * @item: the model group definition
  17846. * @ctxt: the parser context
  17847. * @name: the name
  17848. *
  17849. * Checks for circular references to model group definitions.
  17850. */
  17851. static void
  17852. xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
  17853. xmlSchemaParserCtxtPtr ctxt)
  17854. {
  17855. /*
  17856. * Schema Component Constraint: Model Group Correct
  17857. * 2 Circular groups are disallowed. That is, within the {particles}
  17858. * of a group there must not be at any depth a particle whose {term}
  17859. * is the group itself.
  17860. */
  17861. if ((item == NULL) ||
  17862. (item->type != XML_SCHEMA_TYPE_GROUP) ||
  17863. (item->children == NULL))
  17864. return;
  17865. {
  17866. xmlSchemaTreeItemPtr circ;
  17867. circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
  17868. if (circ != NULL) {
  17869. xmlChar *str = NULL;
  17870. /*
  17871. * TODO: The error report is not adequate: this constraint
  17872. * is defined for model groups but not definitions, but since
  17873. * there cannot be any circular model groups without a model group
  17874. * definition (if not using a construction API), we check those
  17875. * defintions only.
  17876. */
  17877. xmlSchemaPCustomErr(ctxt,
  17878. XML_SCHEMAP_MG_PROPS_CORRECT_2,
  17879. NULL, WXS_ITEM_NODE(circ),
  17880. "Circular reference to the model group definition '%s' "
  17881. "defined", xmlSchemaFormatQName(&str,
  17882. item->targetNamespace, item->name));
  17883. FREE_AND_NULL(str)
  17884. /*
  17885. * NOTE: We will cut the reference to avoid further
  17886. * confusion of the processor. This is a fatal error.
  17887. */
  17888. circ->children = NULL;
  17889. }
  17890. }
  17891. }
  17892. /**
  17893. * xmlSchemaModelGroupToModelGroupDefFixup:
  17894. * @ctxt: the parser context
  17895. * @mg: the model group
  17896. *
  17897. * Assigns the model group of model group definitions to the "term"
  17898. * of the referencing particle.
  17899. * In xmlSchemaResolveModelGroupParticleReferences the model group
  17900. * definitions were assigned to the "term", since needed for the
  17901. * circularity check.
  17902. *
  17903. * Schema Component Constraint:
  17904. * All Group Limited (cos-all-limited) (1.2)
  17905. */
  17906. static void
  17907. xmlSchemaModelGroupToModelGroupDefFixup(
  17908. xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  17909. xmlSchemaModelGroupPtr mg)
  17910. {
  17911. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  17912. while (particle != NULL) {
  17913. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  17914. ((WXS_PARTICLE_TERM(particle))->type !=
  17915. XML_SCHEMA_TYPE_GROUP))
  17916. {
  17917. particle = WXS_PTC_CAST particle->next;
  17918. continue;
  17919. }
  17920. if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
  17921. /*
  17922. * TODO: Remove the particle.
  17923. */
  17924. WXS_PARTICLE_TERM(particle) = NULL;
  17925. particle = WXS_PTC_CAST particle->next;
  17926. continue;
  17927. }
  17928. /*
  17929. * Assign the model group to the {term} of the particle.
  17930. */
  17931. WXS_PARTICLE_TERM(particle) =
  17932. WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
  17933. particle = WXS_PTC_CAST particle->next;
  17934. }
  17935. }
  17936. /**
  17937. * xmlSchemaCheckAttrGroupCircularRecur:
  17938. * @ctxtGr: the searched attribute group
  17939. * @attr: the current attribute list to be processed
  17940. *
  17941. * This one is intended to be used by
  17942. * xmlSchemaCheckAttrGroupCircular only.
  17943. *
  17944. * Returns the circular attribute grou reference, otherwise NULL.
  17945. */
  17946. static xmlSchemaQNameRefPtr
  17947. xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
  17948. xmlSchemaItemListPtr list)
  17949. {
  17950. xmlSchemaAttributeGroupPtr gr;
  17951. xmlSchemaQNameRefPtr ref, circ;
  17952. int i;
  17953. /*
  17954. * We will search for an attribute group reference which
  17955. * references the context attribute group.
  17956. */
  17957. for (i = 0; i < list->nbItems; i++) {
  17958. ref = list->items[i];
  17959. if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  17960. (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  17961. (ref->item != NULL))
  17962. {
  17963. gr = WXS_ATTR_GROUP_CAST ref->item;
  17964. if (gr == ctxtGr)
  17965. return(ref);
  17966. if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
  17967. continue;
  17968. /*
  17969. * Mark as visited to avoid infinite recursion on
  17970. * circular references not yet examined.
  17971. */
  17972. if ((gr->attrUses) &&
  17973. (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
  17974. {
  17975. gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
  17976. circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
  17977. (xmlSchemaItemListPtr) gr->attrUses);
  17978. gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
  17979. if (circ != NULL)
  17980. return (circ);
  17981. }
  17982. }
  17983. }
  17984. return (NULL);
  17985. }
  17986. /**
  17987. * xmlSchemaCheckAttrGroupCircular:
  17988. * attrGr: the attribute group definition
  17989. * @ctxt: the parser context
  17990. * @name: the name
  17991. *
  17992. * Checks for circular references of attribute groups.
  17993. */
  17994. static int
  17995. xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
  17996. xmlSchemaParserCtxtPtr ctxt)
  17997. {
  17998. /*
  17999. * Schema Representation Constraint:
  18000. * Attribute Group Definition Representation OK
  18001. * 3 Circular group reference is disallowed outside <redefine>.
  18002. * That is, unless this element information item's parent is
  18003. * <redefine>, then among the [children], if any, there must
  18004. * not be an <attributeGroup> with ref [attribute] which resolves
  18005. * to the component corresponding to this <attributeGroup>. Indirect
  18006. * circularity is also ruled out. That is, when QName resolution
  18007. * (Schema Document) (�3.15.3) is applied to a �QName� arising from
  18008. * any <attributeGroup>s with a ref [attribute] among the [children],
  18009. * it must not be the case that a �QName� is encountered at any depth
  18010. * which resolves to the component corresponding to this <attributeGroup>.
  18011. */
  18012. if (attrGr->attrUses == NULL)
  18013. return(0);
  18014. else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
  18015. return(0);
  18016. else {
  18017. xmlSchemaQNameRefPtr circ;
  18018. circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
  18019. (xmlSchemaItemListPtr) attrGr->attrUses);
  18020. if (circ != NULL) {
  18021. xmlChar *str = NULL;
  18022. /*
  18023. * TODO: Report the referenced attr group as QName.
  18024. */
  18025. xmlSchemaPCustomErr(ctxt,
  18026. XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
  18027. NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
  18028. "Circular reference to the attribute group '%s' "
  18029. "defined", xmlSchemaGetComponentQName(&str, attrGr));
  18030. FREE_AND_NULL(str);
  18031. /*
  18032. * NOTE: We will cut the reference to avoid further
  18033. * confusion of the processor.
  18034. * BADSPEC TODO: The spec should define how to process in this case.
  18035. */
  18036. circ->item = NULL;
  18037. return(ctxt->err);
  18038. }
  18039. }
  18040. return(0);
  18041. }
  18042. static int
  18043. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18044. xmlSchemaAttributeGroupPtr attrGr);
  18045. /**
  18046. * xmlSchemaExpandAttributeGroupRefs:
  18047. * @pctxt: the parser context
  18048. * @node: the node of the component holding the attribute uses
  18049. * @completeWild: the intersected wildcard to be returned
  18050. * @list: the attribute uses
  18051. *
  18052. * Substitutes contained attribute group references
  18053. * for their attribute uses. Wilcards are intersected.
  18054. * Attribute use prohibitions are removed from the list
  18055. * and returned via the @prohibs list.
  18056. * Pointlessness of attr. prohibs, if a matching attr. decl
  18057. * is existent a well, are checked.
  18058. */
  18059. static int
  18060. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  18061. xmlSchemaBasicItemPtr item,
  18062. xmlSchemaWildcardPtr *completeWild,
  18063. xmlSchemaItemListPtr list,
  18064. xmlSchemaItemListPtr prohibs)
  18065. {
  18066. xmlSchemaAttributeGroupPtr gr;
  18067. xmlSchemaAttributeUsePtr use;
  18068. xmlSchemaItemListPtr sublist;
  18069. int i, j;
  18070. int created = (*completeWild == NULL) ? 0 : 1;
  18071. if (prohibs)
  18072. prohibs->nbItems = 0;
  18073. for (i = 0; i < list->nbItems; i++) {
  18074. use = list->items[i];
  18075. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  18076. if (prohibs == NULL) {
  18077. PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
  18078. "unexpected attr prohibition found");
  18079. return(-1);
  18080. }
  18081. /*
  18082. * Remove from attribute uses.
  18083. */
  18084. if (xmlSchemaItemListRemove(list, i) == -1)
  18085. return(-1);
  18086. i--;
  18087. /*
  18088. * Note that duplicate prohibitions were already
  18089. * handled at parsing time.
  18090. */
  18091. /*
  18092. * Add to list of prohibitions.
  18093. */
  18094. xmlSchemaItemListAddSize(prohibs, 2, use);
  18095. continue;
  18096. }
  18097. if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18098. ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
  18099. {
  18100. if ((WXS_QNAME_CAST use)->item == NULL)
  18101. return(-1);
  18102. gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
  18103. /*
  18104. * Expand the referenced attr. group.
  18105. * TODO: remove this, this is done in a previous step, so
  18106. * already done here.
  18107. */
  18108. if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
  18109. if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
  18110. return(-1);
  18111. }
  18112. /*
  18113. * Build the 'complete' wildcard; i.e. intersect multiple
  18114. * wildcards.
  18115. */
  18116. if (gr->attributeWildcard != NULL) {
  18117. if (*completeWild == NULL) {
  18118. *completeWild = gr->attributeWildcard;
  18119. } else {
  18120. if (! created) {
  18121. xmlSchemaWildcardPtr tmpWild;
  18122. /*
  18123. * Copy the first encountered wildcard as context,
  18124. * except for the annotation.
  18125. *
  18126. * Although the complete wildcard might not correspond
  18127. * to any node in the schema, we will anchor it on
  18128. * the node of the owner component.
  18129. */
  18130. tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
  18131. XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  18132. WXS_ITEM_NODE(item));
  18133. if (tmpWild == NULL)
  18134. return(-1);
  18135. if (xmlSchemaCloneWildcardNsConstraints(pctxt,
  18136. tmpWild, *completeWild) == -1)
  18137. return (-1);
  18138. tmpWild->processContents = (*completeWild)->processContents;
  18139. *completeWild = tmpWild;
  18140. created = 1;
  18141. }
  18142. if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
  18143. gr->attributeWildcard) == -1)
  18144. return(-1);
  18145. }
  18146. }
  18147. /*
  18148. * Just remove the reference if the referenced group does not
  18149. * contain any attribute uses.
  18150. */
  18151. sublist = ((xmlSchemaItemListPtr) gr->attrUses);
  18152. if ((sublist == NULL) || sublist->nbItems == 0) {
  18153. if (xmlSchemaItemListRemove(list, i) == -1)
  18154. return(-1);
  18155. i--;
  18156. continue;
  18157. }
  18158. /*
  18159. * Add the attribute uses.
  18160. */
  18161. list->items[i] = sublist->items[0];
  18162. if (sublist->nbItems != 1) {
  18163. for (j = 1; j < sublist->nbItems; j++) {
  18164. i++;
  18165. if (xmlSchemaItemListInsert(list,
  18166. sublist->items[j], i) == -1)
  18167. return(-1);
  18168. }
  18169. }
  18170. }
  18171. }
  18172. /*
  18173. * Handle pointless prohibitions of declared attributes.
  18174. */
  18175. if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
  18176. xmlSchemaAttributeUseProhibPtr prohib;
  18177. for (i = prohibs->nbItems -1; i >= 0; i--) {
  18178. prohib = prohibs->items[i];
  18179. for (j = 0; j < list->nbItems; j++) {
  18180. use = list->items[j];
  18181. if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
  18182. (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
  18183. {
  18184. xmlChar *str = NULL;
  18185. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  18186. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  18187. prohib->node, NULL,
  18188. "Skipping pointless attribute use prohibition "
  18189. "'%s', since a corresponding attribute use "
  18190. "exists already in the type definition",
  18191. xmlSchemaFormatQName(&str,
  18192. prohib->targetNamespace, prohib->name),
  18193. NULL, NULL);
  18194. FREE_AND_NULL(str);
  18195. /*
  18196. * Remove the prohibition.
  18197. */
  18198. if (xmlSchemaItemListRemove(prohibs, i) == -1)
  18199. return(-1);
  18200. break;
  18201. }
  18202. }
  18203. }
  18204. }
  18205. return(0);
  18206. }
  18207. /**
  18208. * xmlSchemaAttributeGroupExpandRefs:
  18209. * @pctxt: the parser context
  18210. * @attrGr: the attribute group definition
  18211. *
  18212. * Computation of:
  18213. * {attribute uses} property
  18214. * {attribute wildcard} property
  18215. *
  18216. * Substitutes contained attribute group references
  18217. * for their attribute uses. Wilcards are intersected.
  18218. */
  18219. static int
  18220. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18221. xmlSchemaAttributeGroupPtr attrGr)
  18222. {
  18223. if ((attrGr->attrUses == NULL) ||
  18224. (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
  18225. return(0);
  18226. attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
  18227. if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
  18228. &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
  18229. return(-1);
  18230. return(0);
  18231. }
  18232. /**
  18233. * xmlSchemaAttributeGroupExpandRefs:
  18234. * @pctxt: the parser context
  18235. * @attrGr: the attribute group definition
  18236. *
  18237. * Substitutes contained attribute group references
  18238. * for their attribute uses. Wilcards are intersected.
  18239. *
  18240. * Schema Component Constraint:
  18241. * Attribute Group Definition Properties Correct (ag-props-correct)
  18242. */
  18243. static int
  18244. xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18245. xmlSchemaAttributeGroupPtr attrGr)
  18246. {
  18247. /*
  18248. * SPEC ag-props-correct
  18249. * (1) "The values of the properties of an attribute group definition
  18250. * must be as described in the property tableau in The Attribute
  18251. * Group Definition Schema Component (�3.6.1), modulo the impact of
  18252. * Missing Sub-components (�5.3);"
  18253. */
  18254. if ((attrGr->attrUses != NULL) &&
  18255. (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
  18256. {
  18257. xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
  18258. xmlSchemaAttributeUsePtr use, tmp;
  18259. int i, j, hasId = 0;
  18260. for (i = uses->nbItems -1; i >= 0; i--) {
  18261. use = uses->items[i];
  18262. /*
  18263. * SPEC ag-props-correct
  18264. * (2) "Two distinct members of the {attribute uses} must not have
  18265. * {attribute declaration}s both of whose {name}s match and whose
  18266. * {target namespace}s are identical."
  18267. */
  18268. if (i > 0) {
  18269. for (j = i -1; j >= 0; j--) {
  18270. tmp = uses->items[j];
  18271. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  18272. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  18273. (WXS_ATTRUSE_DECL_TNS(use) ==
  18274. WXS_ATTRUSE_DECL_TNS(tmp)))
  18275. {
  18276. xmlChar *str = NULL;
  18277. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18278. XML_SCHEMAP_AG_PROPS_CORRECT,
  18279. attrGr->node, WXS_BASIC_CAST attrGr,
  18280. "Duplicate %s",
  18281. xmlSchemaGetComponentDesignation(&str, use),
  18282. NULL);
  18283. FREE_AND_NULL(str);
  18284. /*
  18285. * Remove the duplicate.
  18286. */
  18287. if (xmlSchemaItemListRemove(uses, i) == -1)
  18288. return(-1);
  18289. goto next_use;
  18290. }
  18291. }
  18292. }
  18293. /*
  18294. * SPEC ag-props-correct
  18295. * (3) "Two distinct members of the {attribute uses} must not have
  18296. * {attribute declaration}s both of whose {type definition}s are or
  18297. * are derived from ID."
  18298. * TODO: Does 'derived' include member-types of unions?
  18299. */
  18300. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  18301. if (xmlSchemaIsDerivedFromBuiltInType(
  18302. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  18303. {
  18304. if (hasId) {
  18305. xmlChar *str = NULL;
  18306. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18307. XML_SCHEMAP_AG_PROPS_CORRECT,
  18308. attrGr->node, WXS_BASIC_CAST attrGr,
  18309. "There must not exist more than one attribute "
  18310. "declaration of type 'xs:ID' "
  18311. "(or derived from 'xs:ID'). The %s violates this "
  18312. "constraint",
  18313. xmlSchemaGetComponentDesignation(&str, use),
  18314. NULL);
  18315. FREE_AND_NULL(str);
  18316. if (xmlSchemaItemListRemove(uses, i) == -1)
  18317. return(-1);
  18318. }
  18319. hasId = 1;
  18320. }
  18321. }
  18322. next_use: {}
  18323. }
  18324. }
  18325. return(0);
  18326. }
  18327. /**
  18328. * xmlSchemaResolveAttrGroupReferences:
  18329. * @attrgrpDecl: the schema attribute definition
  18330. * @ctxt: the schema parser context
  18331. * @name: the attribute name
  18332. *
  18333. * Resolves references to attribute group definitions.
  18334. */
  18335. static int
  18336. xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
  18337. xmlSchemaParserCtxtPtr ctxt)
  18338. {
  18339. xmlSchemaAttributeGroupPtr group;
  18340. if (ref->item != NULL)
  18341. return(0);
  18342. group = xmlSchemaGetAttributeGroup(ctxt->schema,
  18343. ref->name,
  18344. ref->targetNamespace);
  18345. if (group == NULL) {
  18346. xmlSchemaPResCompAttrErr(ctxt,
  18347. XML_SCHEMAP_SRC_RESOLVE,
  18348. NULL, ref->node,
  18349. "ref", ref->name, ref->targetNamespace,
  18350. ref->itemType, NULL);
  18351. return(ctxt->err);
  18352. }
  18353. ref->item = WXS_BASIC_CAST group;
  18354. return(0);
  18355. }
  18356. /**
  18357. * xmlSchemaCheckAttrPropsCorrect:
  18358. * @item: an schema attribute declaration/use
  18359. * @ctxt: a schema parser context
  18360. * @name: the name of the attribute
  18361. *
  18362. *
  18363. * Schema Component Constraint:
  18364. * Attribute Declaration Properties Correct (a-props-correct)
  18365. *
  18366. * Validates the value constraints of an attribute declaration/use.
  18367. * NOTE that this needs the simle type definitions to be already
  18368. * builded and checked.
  18369. */
  18370. static int
  18371. xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18372. xmlSchemaAttributePtr attr)
  18373. {
  18374. /*
  18375. * SPEC a-props-correct (1)
  18376. * "The values of the properties of an attribute declaration must
  18377. * be as described in the property tableau in The Attribute
  18378. * Declaration Schema Component (�3.2.1), modulo the impact of
  18379. * Missing Sub-components (�5.3)."
  18380. */
  18381. if (WXS_ATTR_TYPEDEF(attr) == NULL)
  18382. return(0);
  18383. if (attr->defValue != NULL) {
  18384. int ret;
  18385. /*
  18386. * SPEC a-props-correct (3)
  18387. * "If the {type definition} is or is derived from ID then there
  18388. * must not be a {value constraint}."
  18389. */
  18390. if (xmlSchemaIsDerivedFromBuiltInType(
  18391. WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
  18392. {
  18393. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18394. XML_SCHEMAP_A_PROPS_CORRECT_3,
  18395. NULL, WXS_BASIC_CAST attr,
  18396. "Value constraints are not allowed if the type definition "
  18397. "is or is derived from xs:ID",
  18398. NULL, NULL);
  18399. return(pctxt->err);
  18400. }
  18401. /*
  18402. * SPEC a-props-correct (2)
  18403. * "if there is a {value constraint}, the canonical lexical
  18404. * representation of its value must be �valid� with respect
  18405. * to the {type definition} as defined in String Valid (�3.14.4)."
  18406. * TODO: Don't care about the *cononical* stuff here, this requirement
  18407. * will be removed in WXS 1.1 anyway.
  18408. */
  18409. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
  18410. attr->node, WXS_ATTR_TYPEDEF(attr),
  18411. attr->defValue, &(attr->defVal),
  18412. 1, 1, 0);
  18413. if (ret != 0) {
  18414. if (ret < 0) {
  18415. PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
  18416. "calling xmlSchemaVCheckCVCSimpleType()");
  18417. return(-1);
  18418. }
  18419. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18420. XML_SCHEMAP_A_PROPS_CORRECT_2,
  18421. NULL, WXS_BASIC_CAST attr,
  18422. "The value of the value constraint is not valid",
  18423. NULL, NULL);
  18424. return(pctxt->err);
  18425. }
  18426. }
  18427. return(0);
  18428. }
  18429. static xmlSchemaElementPtr
  18430. xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
  18431. xmlSchemaElementPtr ancestor)
  18432. {
  18433. xmlSchemaElementPtr ret;
  18434. if (WXS_SUBST_HEAD(ancestor) == NULL)
  18435. return (NULL);
  18436. if (WXS_SUBST_HEAD(ancestor) == elemDecl)
  18437. return (ancestor);
  18438. if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
  18439. return (NULL);
  18440. WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
  18441. ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
  18442. WXS_SUBST_HEAD(ancestor));
  18443. WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
  18444. return (ret);
  18445. }
  18446. /**
  18447. * xmlSchemaCheckElemPropsCorrect:
  18448. * @ctxt: a schema parser context
  18449. * @decl: the element declaration
  18450. * @name: the name of the attribute
  18451. *
  18452. * Schema Component Constraint:
  18453. * Element Declaration Properties Correct (e-props-correct)
  18454. *
  18455. * STATUS:
  18456. * missing: (6)
  18457. */
  18458. static int
  18459. xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18460. xmlSchemaElementPtr elemDecl)
  18461. {
  18462. int ret = 0;
  18463. xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
  18464. /*
  18465. * SPEC (1) "The values of the properties of an element declaration
  18466. * must be as described in the property tableau in The Element
  18467. * Declaration Schema Component (�3.3.1), modulo the impact of Missing
  18468. * Sub-components (�5.3)."
  18469. */
  18470. if (WXS_SUBST_HEAD(elemDecl) != NULL) {
  18471. xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
  18472. xmlSchemaCheckElementDeclComponent(head, pctxt);
  18473. /*
  18474. * SPEC (3) "If there is a non-�absent� {substitution group
  18475. * affiliation}, then {scope} must be global."
  18476. */
  18477. if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
  18478. xmlSchemaPCustomErr(pctxt,
  18479. XML_SCHEMAP_E_PROPS_CORRECT_3,
  18480. WXS_BASIC_CAST elemDecl, NULL,
  18481. "Only global element declarations can have a "
  18482. "substitution group affiliation", NULL);
  18483. ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
  18484. }
  18485. /*
  18486. * TODO: SPEC (6) "Circular substitution groups are disallowed.
  18487. * That is, it must not be possible to return to an element declaration
  18488. * by repeatedly following the {substitution group affiliation}
  18489. * property."
  18490. */
  18491. if (head == elemDecl)
  18492. circ = head;
  18493. else if (WXS_SUBST_HEAD(head) != NULL)
  18494. circ = xmlSchemaCheckSubstGroupCircular(head, head);
  18495. else
  18496. circ = NULL;
  18497. if (circ != NULL) {
  18498. xmlChar *strA = NULL, *strB = NULL;
  18499. xmlSchemaPCustomErrExt(pctxt,
  18500. XML_SCHEMAP_E_PROPS_CORRECT_6,
  18501. WXS_BASIC_CAST circ, NULL,
  18502. "The element declaration '%s' defines a circular "
  18503. "substitution group to element declaration '%s'",
  18504. xmlSchemaGetComponentQName(&strA, circ),
  18505. xmlSchemaGetComponentQName(&strB, head),
  18506. NULL);
  18507. FREE_AND_NULL(strA)
  18508. FREE_AND_NULL(strB)
  18509. ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
  18510. }
  18511. /*
  18512. * SPEC (4) "If there is a {substitution group affiliation},
  18513. * the {type definition}
  18514. * of the element declaration must be validly derived from the {type
  18515. * definition} of the {substitution group affiliation}, given the value
  18516. * of the {substitution group exclusions} of the {substitution group
  18517. * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
  18518. * (if the {type definition} is complex) or as defined in
  18519. * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
  18520. * simple)."
  18521. *
  18522. * NOTE: {substitution group exclusions} means the values of the
  18523. * attribute "final".
  18524. */
  18525. if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
  18526. int set = 0;
  18527. if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
  18528. set |= SUBSET_EXTENSION;
  18529. if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
  18530. set |= SUBSET_RESTRICTION;
  18531. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
  18532. WXS_ELEM_TYPEDEF(head), set) != 0) {
  18533. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  18534. ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
  18535. xmlSchemaPCustomErrExt(pctxt,
  18536. XML_SCHEMAP_E_PROPS_CORRECT_4,
  18537. WXS_BASIC_CAST elemDecl, NULL,
  18538. "The type definition '%s' was "
  18539. "either rejected by the substitution group "
  18540. "affiliation '%s', or not validly derived from its type "
  18541. "definition '%s'",
  18542. xmlSchemaGetComponentQName(&strA, typeDef),
  18543. xmlSchemaGetComponentQName(&strB, head),
  18544. xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
  18545. FREE_AND_NULL(strA)
  18546. FREE_AND_NULL(strB)
  18547. FREE_AND_NULL(strC)
  18548. }
  18549. }
  18550. }
  18551. /*
  18552. * SPEC (5) "If the {type definition} or {type definition}'s
  18553. * {content type}
  18554. * is or is derived from ID then there must not be a {value constraint}.
  18555. * Note: The use of ID as a type definition for elements goes beyond
  18556. * XML 1.0, and should be avoided if backwards compatibility is desired"
  18557. */
  18558. if ((elemDecl->value != NULL) &&
  18559. ((WXS_IS_SIMPLE(typeDef) &&
  18560. xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
  18561. (WXS_IS_COMPLEX(typeDef) &&
  18562. WXS_HAS_SIMPLE_CONTENT(typeDef) &&
  18563. xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
  18564. XML_SCHEMAS_ID)))) {
  18565. ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
  18566. xmlSchemaPCustomErr(pctxt,
  18567. XML_SCHEMAP_E_PROPS_CORRECT_5,
  18568. WXS_BASIC_CAST elemDecl, NULL,
  18569. "The type definition (or type definition's content type) is or "
  18570. "is derived from ID; value constraints are not allowed in "
  18571. "conjunction with such a type definition", NULL);
  18572. } else if (elemDecl->value != NULL) {
  18573. int vcret;
  18574. xmlNodePtr node = NULL;
  18575. /*
  18576. * SPEC (2) "If there is a {value constraint}, the canonical lexical
  18577. * representation of its value must be �valid� with respect to the
  18578. * {type definition} as defined in Element Default Valid (Immediate)
  18579. * (�3.3.6)."
  18580. */
  18581. if (typeDef == NULL) {
  18582. xmlSchemaPErr(pctxt, elemDecl->node,
  18583. XML_SCHEMAP_INTERNAL,
  18584. "Internal error: xmlSchemaCheckElemPropsCorrect, "
  18585. "type is missing... skipping validation of "
  18586. "the value constraint", NULL, NULL);
  18587. return (-1);
  18588. }
  18589. if (elemDecl->node != NULL) {
  18590. if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
  18591. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18592. BAD_CAST "fixed");
  18593. else
  18594. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18595. BAD_CAST "default");
  18596. }
  18597. vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
  18598. typeDef, elemDecl->value, &(elemDecl->defVal));
  18599. if (vcret != 0) {
  18600. if (vcret < 0) {
  18601. PERROR_INT("xmlSchemaElemCheckValConstr",
  18602. "failed to validate the value constraint of an "
  18603. "element declaration");
  18604. return (-1);
  18605. }
  18606. return (vcret);
  18607. }
  18608. }
  18609. return (ret);
  18610. }
  18611. /**
  18612. * xmlSchemaCheckElemSubstGroup:
  18613. * @ctxt: a schema parser context
  18614. * @decl: the element declaration
  18615. * @name: the name of the attribute
  18616. *
  18617. * Schema Component Constraint:
  18618. * Substitution Group (cos-equiv-class)
  18619. *
  18620. * In Libxml2 the subst. groups will be precomputed, in terms of that
  18621. * a list will be built for each subst. group head, holding all direct
  18622. * referents to this head.
  18623. * NOTE that this function needs:
  18624. * 1. circular subst. groups to be checked beforehand
  18625. * 2. the declaration's type to be derived from the head's type
  18626. *
  18627. * STATUS:
  18628. *
  18629. */
  18630. static void
  18631. xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
  18632. xmlSchemaElementPtr elemDecl)
  18633. {
  18634. if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
  18635. /* SPEC (1) "Its {abstract} is false." */
  18636. (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
  18637. return;
  18638. {
  18639. xmlSchemaElementPtr head;
  18640. xmlSchemaTypePtr headType, type;
  18641. int set, methSet;
  18642. /*
  18643. * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
  18644. * {disallowed substitutions} as the blocking constraint, as defined in
  18645. * Substitution Group OK (Transitive) (�3.3.6)."
  18646. */
  18647. for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
  18648. head = WXS_SUBST_HEAD(head)) {
  18649. set = 0;
  18650. methSet = 0;
  18651. /*
  18652. * The blocking constraints.
  18653. */
  18654. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
  18655. continue;
  18656. headType = head->subtypes;
  18657. type = elemDecl->subtypes;
  18658. if (headType == type)
  18659. goto add_member;
  18660. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
  18661. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18662. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
  18663. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18664. /*
  18665. * SPEC: Substitution Group OK (Transitive) (2.3)
  18666. * "The set of all {derivation method}s involved in the
  18667. * derivation of D's {type definition} from C's {type definition}
  18668. * does not intersect with the union of the blocking constraint,
  18669. * C's {prohibited substitutions} (if C is complex, otherwise the
  18670. * empty set) and the {prohibited substitutions} (respectively the
  18671. * empty set) of any intermediate {type definition}s in the
  18672. * derivation of D's {type definition} from C's {type definition}."
  18673. */
  18674. /*
  18675. * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
  18676. * subst.head axis, the methSet does not need to be computed for
  18677. * the full depth over and over.
  18678. */
  18679. /*
  18680. * The set of all {derivation method}s involved in the derivation
  18681. */
  18682. while ((type != NULL) && (type != headType)) {
  18683. if ((WXS_IS_EXTENSION(type)) &&
  18684. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18685. methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18686. if (WXS_IS_RESTRICTION(type) &&
  18687. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18688. methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18689. type = type->baseType;
  18690. }
  18691. /*
  18692. * The {prohibited substitutions} of all intermediate types +
  18693. * the head's type.
  18694. */
  18695. type = elemDecl->subtypes->baseType;
  18696. while (type != NULL) {
  18697. if (WXS_IS_COMPLEX(type)) {
  18698. if ((type->flags &
  18699. XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18700. ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
  18701. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18702. if ((type->flags &
  18703. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18704. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18705. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18706. } else
  18707. break;
  18708. if (type == headType)
  18709. break;
  18710. type = type->baseType;
  18711. }
  18712. if ((set != 0) &&
  18713. (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18714. (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
  18715. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18716. (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
  18717. continue;
  18718. }
  18719. add_member:
  18720. xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
  18721. if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
  18722. head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
  18723. }
  18724. }
  18725. }
  18726. #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
  18727. /**
  18728. * xmlSchemaCheckElementDeclComponent
  18729. * @pctxt: the schema parser context
  18730. * @ctxtComponent: the context component (an element declaration)
  18731. * @ctxtParticle: the first particle of the context component
  18732. * @searchParticle: the element declaration particle to be analysed
  18733. *
  18734. * Schema Component Constraint: Element Declarations Consistent
  18735. */
  18736. static int
  18737. xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
  18738. xmlSchemaBasicItemPtr ctxtComponent,
  18739. xmlSchemaParticlePtr ctxtParticle,
  18740. xmlSchemaParticlePtr searchParticle,
  18741. xmlSchemaParticlePtr curParticle,
  18742. int search)
  18743. {
  18744. return(0);
  18745. int ret = 0;
  18746. xmlSchemaParticlePtr cur = curParticle;
  18747. if (curParticle == NULL) {
  18748. return(0);
  18749. }
  18750. if (WXS_PARTICLE_TERM(curParticle) == NULL) {
  18751. /*
  18752. * Just return in this case. A missing "term" of the particle
  18753. * might arise due to an invalid "term" component.
  18754. */
  18755. return(0);
  18756. }
  18757. while (cur != NULL) {
  18758. switch (WXS_PARTICLE_TERM(cur)->type) {
  18759. case XML_SCHEMA_TYPE_ANY:
  18760. break;
  18761. case XML_SCHEMA_TYPE_ELEMENT:
  18762. if (search == 0) {
  18763. ret = xmlSchemaCheckElementDeclConsistent(pctxt,
  18764. ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
  18765. if (ret != 0)
  18766. return(ret);
  18767. } else {
  18768. xmlSchemaElementPtr elem =
  18769. WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
  18770. /*
  18771. * SPEC Element Declarations Consistent:
  18772. * "If the {particles} contains, either directly,
  18773. * indirectly (that is, within the {particles} of a
  18774. * contained model group, recursively) or �implicitly�
  18775. * two or more element declaration particles with
  18776. * the same {name} and {target namespace}, then
  18777. * all their type definitions must be the same
  18778. * top-level definition [...]"
  18779. */
  18780. if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
  18781. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
  18782. xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18783. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
  18784. {
  18785. xmlChar *strA = NULL, *strB = NULL;
  18786. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18787. /* TODO: error code */
  18788. XML_SCHEMAP_COS_NONAMBIG,
  18789. WXS_ITEM_NODE(cur), NULL,
  18790. "In the content model of %s, there are multiple "
  18791. "element declarations for '%s' with different "
  18792. "type definitions",
  18793. xmlSchemaGetComponentDesignation(&strA,
  18794. ctxtComponent),
  18795. xmlSchemaFormatQName(&strB,
  18796. WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18797. WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
  18798. FREE_AND_NULL(strA);
  18799. FREE_AND_NULL(strB);
  18800. return(XML_SCHEMAP_COS_NONAMBIG);
  18801. }
  18802. }
  18803. break;
  18804. case XML_SCHEMA_TYPE_SEQUENCE: {
  18805. break;
  18806. }
  18807. case XML_SCHEMA_TYPE_CHOICE:{
  18808. /*
  18809. xmlSchemaTreeItemPtr sub;
  18810. sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
  18811. while (sub != NULL) {
  18812. ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
  18813. ctxtParticle, ctxtElem);
  18814. if (ret != 0)
  18815. return(ret);
  18816. sub = sub->next;
  18817. }
  18818. */
  18819. break;
  18820. }
  18821. case XML_SCHEMA_TYPE_ALL:
  18822. break;
  18823. case XML_SCHEMA_TYPE_GROUP:
  18824. break;
  18825. default:
  18826. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  18827. "xmlSchemaCheckElementDeclConsistent",
  18828. "found unexpected term of type '%s' in content model",
  18829. WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
  18830. return(-1);
  18831. }
  18832. cur = (xmlSchemaParticlePtr) cur->next;
  18833. }
  18834. exit:
  18835. return(ret);
  18836. }
  18837. #endif
  18838. /**
  18839. * xmlSchemaCheckElementDeclComponent
  18840. * @item: an schema element declaration/particle
  18841. * @ctxt: a schema parser context
  18842. * @name: the name of the attribute
  18843. *
  18844. * Validates the value constraints of an element declaration.
  18845. * Adds substitution group members.
  18846. */
  18847. static void
  18848. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  18849. xmlSchemaParserCtxtPtr ctxt)
  18850. {
  18851. if (elemDecl == NULL)
  18852. return;
  18853. if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
  18854. return;
  18855. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
  18856. if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
  18857. /*
  18858. * Adds substitution group members.
  18859. */
  18860. xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
  18861. }
  18862. }
  18863. /**
  18864. * xmlSchemaResolveModelGroupParticleReferences:
  18865. * @particle: a particle component
  18866. * @ctxt: a parser context
  18867. *
  18868. * Resolves references of a model group's {particles} to
  18869. * model group definitions and to element declarations.
  18870. */
  18871. static void
  18872. xmlSchemaResolveModelGroupParticleReferences(
  18873. xmlSchemaParserCtxtPtr ctxt,
  18874. xmlSchemaModelGroupPtr mg)
  18875. {
  18876. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  18877. xmlSchemaQNameRefPtr ref;
  18878. xmlSchemaBasicItemPtr refItem;
  18879. /*
  18880. * URGENT TODO: Test this.
  18881. */
  18882. while (particle != NULL) {
  18883. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  18884. ((WXS_PARTICLE_TERM(particle))->type !=
  18885. XML_SCHEMA_EXTRA_QNAMEREF))
  18886. {
  18887. goto next_particle;
  18888. }
  18889. ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
  18890. /*
  18891. * Resolve the reference.
  18892. * NULL the {term} by default.
  18893. */
  18894. particle->children = NULL;
  18895. refItem = xmlSchemaGetNamedComponent(ctxt->schema,
  18896. ref->itemType, ref->name, ref->targetNamespace);
  18897. if (refItem == NULL) {
  18898. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  18899. NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
  18900. ref->targetNamespace, ref->itemType, NULL);
  18901. /* TODO: remove the particle. */
  18902. goto next_particle;
  18903. }
  18904. if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
  18905. if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
  18906. /* TODO: remove the particle. */
  18907. goto next_particle;
  18908. /*
  18909. * NOTE that we will assign the model group definition
  18910. * itself to the "term" of the particle. This will ease
  18911. * the check for circular model group definitions. After
  18912. * that the "term" will be assigned the model group of the
  18913. * model group definition.
  18914. */
  18915. if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
  18916. XML_SCHEMA_TYPE_ALL) {
  18917. /*
  18918. * SPEC cos-all-limited (1)
  18919. * SPEC cos-all-limited (1.2)
  18920. * "It appears only as the value of one or both of the
  18921. * following properties:"
  18922. * (1.1) "the {model group} property of a model group
  18923. * definition."
  18924. * (1.2) "the {term} property of a particle [... of] the "
  18925. * {content type} of a complex type definition."
  18926. */
  18927. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  18928. /* TODO: error code */
  18929. XML_SCHEMAP_COS_ALL_LIMITED,
  18930. WXS_ITEM_NODE(particle), NULL,
  18931. "A model group definition is referenced, but "
  18932. "it contains an 'all' model group, which "
  18933. "cannot be contained by model groups",
  18934. NULL, NULL);
  18935. /* TODO: remove the particle. */
  18936. goto next_particle;
  18937. }
  18938. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18939. } else {
  18940. /*
  18941. * TODO: Are referenced element declarations the only
  18942. * other components we expect here?
  18943. */
  18944. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18945. }
  18946. next_particle:
  18947. particle = WXS_PTC_CAST particle->next;
  18948. }
  18949. }
  18950. static int
  18951. xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
  18952. xmlSchemaValPtr y)
  18953. {
  18954. xmlSchemaTypePtr tx, ty, ptx, pty;
  18955. int ret;
  18956. while (x != NULL) {
  18957. /* Same types. */
  18958. tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
  18959. ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
  18960. ptx = xmlSchemaGetPrimitiveType(tx);
  18961. pty = xmlSchemaGetPrimitiveType(ty);
  18962. /*
  18963. * (1) if a datatype T' is �derived� by �restriction� from an
  18964. * atomic datatype T then the �value space� of T' is a subset of
  18965. * the �value space� of T. */
  18966. /*
  18967. * (2) if datatypes T' and T'' are �derived� by �restriction�
  18968. * from a common atomic ancestor T then the �value space�s of T'
  18969. * and T'' may overlap.
  18970. */
  18971. if (ptx != pty)
  18972. return(0);
  18973. /*
  18974. * We assume computed values to be normalized, so do a fast
  18975. * string comparison for string based types.
  18976. */
  18977. if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
  18978. WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
  18979. if (! xmlStrEqual(
  18980. xmlSchemaValueGetAsString(x),
  18981. xmlSchemaValueGetAsString(y)))
  18982. return (0);
  18983. } else {
  18984. ret = xmlSchemaCompareValuesWhtsp(
  18985. x, XML_SCHEMA_WHITESPACE_PRESERVE,
  18986. y, XML_SCHEMA_WHITESPACE_PRESERVE);
  18987. if (ret == -2)
  18988. return(-1);
  18989. if (ret != 0)
  18990. return(0);
  18991. }
  18992. /*
  18993. * Lists.
  18994. */
  18995. x = xmlSchemaValueGetNext(x);
  18996. if (x != NULL) {
  18997. y = xmlSchemaValueGetNext(y);
  18998. if (y == NULL)
  18999. return (0);
  19000. } else if (xmlSchemaValueGetNext(y) != NULL)
  19001. return (0);
  19002. else
  19003. return (1);
  19004. }
  19005. return (0);
  19006. }
  19007. /**
  19008. * xmlSchemaResolveAttrUseReferences:
  19009. * @item: an attribute use
  19010. * @ctxt: a parser context
  19011. *
  19012. * Resolves the referenced attribute declaration.
  19013. */
  19014. static int
  19015. xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
  19016. xmlSchemaParserCtxtPtr ctxt)
  19017. {
  19018. if ((ctxt == NULL) || (ause == NULL))
  19019. return(-1);
  19020. if ((ause->attrDecl == NULL) ||
  19021. (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
  19022. return(0);
  19023. {
  19024. xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
  19025. /*
  19026. * TODO: Evaluate, what errors could occur if the declaration is not
  19027. * found.
  19028. */
  19029. ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
  19030. ref->name, ref->targetNamespace);
  19031. if (ause->attrDecl == NULL) {
  19032. xmlSchemaPResCompAttrErr(ctxt,
  19033. XML_SCHEMAP_SRC_RESOLVE,
  19034. WXS_BASIC_CAST ause, ause->node,
  19035. "ref", ref->name, ref->targetNamespace,
  19036. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19037. return(ctxt->err);;
  19038. }
  19039. }
  19040. return(0);
  19041. }
  19042. /**
  19043. * xmlSchemaCheckAttrUsePropsCorrect:
  19044. * @ctxt: a parser context
  19045. * @use: an attribute use
  19046. *
  19047. * Schema Component Constraint:
  19048. * Attribute Use Correct (au-props-correct)
  19049. *
  19050. */
  19051. static int
  19052. xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  19053. xmlSchemaAttributeUsePtr use)
  19054. {
  19055. if ((ctxt == NULL) || (use == NULL))
  19056. return(-1);
  19057. if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
  19058. ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
  19059. return(0);
  19060. /*
  19061. * SPEC au-props-correct (1)
  19062. * "The values of the properties of an attribute use must be as
  19063. * described in the property tableau in The Attribute Use Schema
  19064. * Component (�3.5.1), modulo the impact of Missing
  19065. * Sub-components (�5.3)."
  19066. */
  19067. if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
  19068. ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
  19069. ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19070. {
  19071. xmlSchemaPCustomErr(ctxt,
  19072. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19073. WXS_BASIC_CAST use, NULL,
  19074. "The attribute declaration has a 'fixed' value constraint "
  19075. ", thus the attribute use must also have a 'fixed' value "
  19076. "constraint",
  19077. NULL);
  19078. return(ctxt->err);
  19079. }
  19080. /*
  19081. * Compute and check the value constraint's value.
  19082. */
  19083. if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
  19084. int ret;
  19085. /*
  19086. * TODO: The spec seems to be missing a check of the
  19087. * value constraint of the attribute use. We will do it here.
  19088. */
  19089. /*
  19090. * SPEC a-props-correct (3)
  19091. */
  19092. if (xmlSchemaIsDerivedFromBuiltInType(
  19093. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  19094. {
  19095. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19096. XML_SCHEMAP_AU_PROPS_CORRECT,
  19097. NULL, WXS_BASIC_CAST use,
  19098. "Value constraints are not allowed if the type definition "
  19099. "is or is derived from xs:ID",
  19100. NULL, NULL);
  19101. return(ctxt->err);
  19102. }
  19103. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
  19104. use->node, WXS_ATTRUSE_TYPEDEF(use),
  19105. use->defValue, &(use->defVal),
  19106. 1, 1, 0);
  19107. if (ret != 0) {
  19108. if (ret < 0) {
  19109. PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
  19110. "calling xmlSchemaVCheckCVCSimpleType()");
  19111. return(-1);
  19112. }
  19113. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19114. XML_SCHEMAP_AU_PROPS_CORRECT,
  19115. NULL, WXS_BASIC_CAST use,
  19116. "The value of the value constraint is not valid",
  19117. NULL, NULL);
  19118. return(ctxt->err);
  19119. }
  19120. }
  19121. /*
  19122. * SPEC au-props-correct (2)
  19123. * "If the {attribute declaration} has a fixed
  19124. * {value constraint}, then if the attribute use itself has a
  19125. * {value constraint}, it must also be fixed and its value must match
  19126. * that of the {attribute declaration}'s {value constraint}."
  19127. */
  19128. if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
  19129. (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19130. {
  19131. if (! xmlSchemaAreValuesEqual(use->defVal,
  19132. (WXS_ATTRUSE_DECL(use))->defVal))
  19133. {
  19134. xmlSchemaPCustomErr(ctxt,
  19135. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19136. WXS_BASIC_CAST use, NULL,
  19137. "The 'fixed' value constraint of the attribute use "
  19138. "must match the attribute declaration's value "
  19139. "constraint '%s'",
  19140. (WXS_ATTRUSE_DECL(use))->defValue);
  19141. }
  19142. return(ctxt->err);
  19143. }
  19144. return(0);
  19145. }
  19146. /**
  19147. * xmlSchemaResolveAttrTypeReferences:
  19148. * @item: an attribute declaration
  19149. * @ctxt: a parser context
  19150. *
  19151. * Resolves the referenced type definition component.
  19152. */
  19153. static int
  19154. xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
  19155. xmlSchemaParserCtxtPtr ctxt)
  19156. {
  19157. /*
  19158. * The simple type definition corresponding to the <simpleType> element
  19159. * information item in the [children], if present, otherwise the simple
  19160. * type definition �resolved� to by the �actual value� of the type
  19161. * [attribute], if present, otherwise the �simple ur-type definition�.
  19162. */
  19163. if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
  19164. return(0);
  19165. item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
  19166. if (item->subtypes != NULL)
  19167. return(0);
  19168. if (item->typeName != NULL) {
  19169. xmlSchemaTypePtr type;
  19170. type = xmlSchemaGetType(ctxt->schema, item->typeName,
  19171. item->typeNs);
  19172. if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
  19173. xmlSchemaPResCompAttrErr(ctxt,
  19174. XML_SCHEMAP_SRC_RESOLVE,
  19175. WXS_BASIC_CAST item, item->node,
  19176. "type", item->typeName, item->typeNs,
  19177. XML_SCHEMA_TYPE_SIMPLE, NULL);
  19178. return(ctxt->err);
  19179. } else
  19180. item->subtypes = type;
  19181. } else {
  19182. /*
  19183. * The type defaults to the xs:anySimpleType.
  19184. */
  19185. item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  19186. }
  19187. return(0);
  19188. }
  19189. /**
  19190. * xmlSchemaResolveIDCKeyReferences:
  19191. * @idc: the identity-constraint definition
  19192. * @ctxt: the schema parser context
  19193. * @name: the attribute name
  19194. *
  19195. * Resolve keyRef references to key/unique IDCs.
  19196. * Schema Component Constraint:
  19197. * Identity-constraint Definition Properties Correct (c-props-correct)
  19198. */
  19199. static int
  19200. xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
  19201. xmlSchemaParserCtxtPtr pctxt)
  19202. {
  19203. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
  19204. return(0);
  19205. if (idc->ref->name != NULL) {
  19206. idc->ref->item = (xmlSchemaBasicItemPtr)
  19207. xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
  19208. idc->ref->targetNamespace);
  19209. if (idc->ref->item == NULL) {
  19210. /*
  19211. * TODO: It is actually not an error to fail to resolve
  19212. * at this stage. BUT we need to be that strict!
  19213. */
  19214. xmlSchemaPResCompAttrErr(pctxt,
  19215. XML_SCHEMAP_SRC_RESOLVE,
  19216. WXS_BASIC_CAST idc, idc->node,
  19217. "refer", idc->ref->name,
  19218. idc->ref->targetNamespace,
  19219. XML_SCHEMA_TYPE_IDC_KEY, NULL);
  19220. return(pctxt->err);
  19221. } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  19222. /*
  19223. * SPEC c-props-correct (1)
  19224. */
  19225. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19226. XML_SCHEMAP_C_PROPS_CORRECT,
  19227. NULL, WXS_BASIC_CAST idc,
  19228. "The keyref references a keyref",
  19229. NULL, NULL);
  19230. idc->ref->item = NULL;
  19231. return(pctxt->err);
  19232. } else {
  19233. if (idc->nbFields !=
  19234. ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
  19235. xmlChar *str = NULL;
  19236. xmlSchemaIDCPtr refer;
  19237. refer = (xmlSchemaIDCPtr) idc->ref->item;
  19238. /*
  19239. * SPEC c-props-correct(2)
  19240. * "If the {identity-constraint category} is keyref,
  19241. * the cardinality of the {fields} must equal that of
  19242. * the {fields} of the {referenced key}.
  19243. */
  19244. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19245. XML_SCHEMAP_C_PROPS_CORRECT,
  19246. NULL, WXS_BASIC_CAST idc,
  19247. "The cardinality of the keyref differs from the "
  19248. "cardinality of the referenced key/unique '%s'",
  19249. xmlSchemaFormatQName(&str, refer->targetNamespace,
  19250. refer->name),
  19251. NULL);
  19252. FREE_AND_NULL(str)
  19253. return(pctxt->err);
  19254. }
  19255. }
  19256. }
  19257. return(0);
  19258. }
  19259. static int
  19260. xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
  19261. xmlSchemaParserCtxtPtr pctxt)
  19262. {
  19263. if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
  19264. prohib->targetNamespace) == NULL) {
  19265. xmlSchemaPResCompAttrErr(pctxt,
  19266. XML_SCHEMAP_SRC_RESOLVE,
  19267. NULL, prohib->node,
  19268. "ref", prohib->name, prohib->targetNamespace,
  19269. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19270. return(XML_SCHEMAP_SRC_RESOLVE);
  19271. }
  19272. return(0);
  19273. }
  19274. #define WXS_REDEFINED_TYPE(c) \
  19275. (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
  19276. #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
  19277. (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19278. #define WXS_REDEFINED_ATTR_GROUP(c) \
  19279. (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19280. static int
  19281. xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
  19282. {
  19283. int err = 0;
  19284. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19285. xmlSchemaBasicItemPtr prev, item;
  19286. int wasRedefined;
  19287. if (redef == NULL)
  19288. return(0);
  19289. do {
  19290. item = redef->item;
  19291. /*
  19292. * First try to locate the redefined component in the
  19293. * schema graph starting with the redefined schema.
  19294. * NOTE: According to this schema bug entry:
  19295. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
  19296. * it's not clear if the referenced component needs to originate
  19297. * from the <redefine>d schema _document_ or the schema; the latter
  19298. * would include all imported and included sub-schemas of the
  19299. * <redefine>d schema. Currenlty we latter approach is used.
  19300. * SUPPLEMENT: It seems that the WG moves towards the latter
  19301. * approach, so we are doing it right.
  19302. *
  19303. */
  19304. prev = xmlSchemaFindRedefCompInGraph(
  19305. redef->targetBucket, item->type,
  19306. redef->refName, redef->refTargetNs);
  19307. if (prev == NULL) {
  19308. xmlChar *str = NULL;
  19309. xmlNodePtr node;
  19310. /*
  19311. * SPEC src-redefine:
  19312. * (6.2.1) "The �actual value� of its own name attribute plus
  19313. * target namespace must successfully �resolve� to a model
  19314. * group definition in I."
  19315. * (7.2.1) "The �actual value� of its own name attribute plus
  19316. * target namespace must successfully �resolve� to an attribute
  19317. * group definition in I."
  19318. *
  19319. * Note that, if we are redefining with the use of references
  19320. * to components, the spec assumes the src-resolve to be used;
  19321. * but this won't assure that we search only *inside* the
  19322. * redefined schema.
  19323. */
  19324. if (redef->reference)
  19325. node = WXS_ITEM_NODE(redef->reference);
  19326. else
  19327. node = WXS_ITEM_NODE(item);
  19328. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19329. /*
  19330. * TODO: error code.
  19331. * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
  19332. * reference kind.
  19333. */
  19334. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  19335. "The %s '%s' to be redefined could not be found in "
  19336. "the redefined schema",
  19337. WXS_ITEM_TYPE_NAME(item),
  19338. xmlSchemaFormatQName(&str, redef->refTargetNs,
  19339. redef->refName));
  19340. FREE_AND_NULL(str);
  19341. err = pctxt->err;
  19342. redef = redef->next;
  19343. continue;
  19344. }
  19345. /*
  19346. * TODO: Obtaining and setting the redefinition state is really
  19347. * clumsy.
  19348. */
  19349. wasRedefined = 0;
  19350. switch (item->type) {
  19351. case XML_SCHEMA_TYPE_COMPLEX:
  19352. case XML_SCHEMA_TYPE_SIMPLE:
  19353. if ((WXS_TYPE_CAST prev)->flags &
  19354. XML_SCHEMAS_TYPE_REDEFINED)
  19355. {
  19356. wasRedefined = 1;
  19357. break;
  19358. }
  19359. /* Mark it as redefined. */
  19360. (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
  19361. /*
  19362. * Assign the redefined type to the
  19363. * base type of the redefining type.
  19364. * TODO: How
  19365. */
  19366. ((xmlSchemaTypePtr) item)->baseType =
  19367. (xmlSchemaTypePtr) prev;
  19368. break;
  19369. case XML_SCHEMA_TYPE_GROUP:
  19370. if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
  19371. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19372. {
  19373. wasRedefined = 1;
  19374. break;
  19375. }
  19376. /* Mark it as redefined. */
  19377. (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
  19378. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
  19379. if (redef->reference != NULL) {
  19380. /*
  19381. * Overwrite the QName-reference with the
  19382. * referenced model group def.
  19383. */
  19384. (WXS_PTC_CAST redef->reference)->children =
  19385. WXS_TREE_CAST prev;
  19386. }
  19387. redef->target = prev;
  19388. break;
  19389. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19390. if ((WXS_ATTR_GROUP_CAST prev)->flags &
  19391. XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19392. {
  19393. wasRedefined = 1;
  19394. break;
  19395. }
  19396. (WXS_ATTR_GROUP_CAST prev)->flags |=
  19397. XML_SCHEMAS_ATTRGROUP_REDEFINED;
  19398. if (redef->reference != NULL) {
  19399. /*
  19400. * Assign the redefined attribute group to the
  19401. * QName-reference component.
  19402. * This is the easy case, since we will just
  19403. * expand the redefined group.
  19404. */
  19405. (WXS_QNAME_CAST redef->reference)->item = prev;
  19406. redef->target = NULL;
  19407. } else {
  19408. /*
  19409. * This is the complicated case: we need
  19410. * to apply src-redefine (7.2.2) at a later
  19411. * stage, i.e. when attribute group references
  19412. * have beed expanded and simple types have
  19413. * beed fixed.
  19414. */
  19415. redef->target = prev;
  19416. }
  19417. break;
  19418. default:
  19419. PERROR_INT("xmlSchemaResolveRedefReferences",
  19420. "Unexpected redefined component type");
  19421. return(-1);
  19422. }
  19423. if (wasRedefined) {
  19424. xmlChar *str = NULL;
  19425. xmlNodePtr node;
  19426. if (redef->reference)
  19427. node = WXS_ITEM_NODE(redef->reference);
  19428. else
  19429. node = WXS_ITEM_NODE(redef->item);
  19430. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19431. /* TODO: error code. */
  19432. XML_SCHEMAP_SRC_REDEFINE,
  19433. node, NULL,
  19434. "The referenced %s was already redefined. Multiple "
  19435. "redefinition of the same component is not supported",
  19436. xmlSchemaGetComponentDesignation(&str, prev),
  19437. NULL);
  19438. FREE_AND_NULL(str)
  19439. err = pctxt->err;
  19440. redef = redef->next;
  19441. continue;
  19442. }
  19443. redef = redef->next;
  19444. } while (redef != NULL);
  19445. return(err);
  19446. }
  19447. static int
  19448. xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
  19449. {
  19450. int err = 0;
  19451. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19452. xmlSchemaBasicItemPtr item;
  19453. if (redef == NULL)
  19454. return(0);
  19455. do {
  19456. if (redef->target == NULL) {
  19457. redef = redef->next;
  19458. continue;
  19459. }
  19460. item = redef->item;
  19461. switch (item->type) {
  19462. case XML_SCHEMA_TYPE_SIMPLE:
  19463. case XML_SCHEMA_TYPE_COMPLEX:
  19464. /*
  19465. * Since the spec wants the {name} of the redefined
  19466. * type to be 'absent', we'll NULL it.
  19467. */
  19468. (WXS_TYPE_CAST redef->target)->name = NULL;
  19469. /*
  19470. * TODO: Seems like there's nothing more to do. The normal
  19471. * inheritance mechanism is used. But not 100% sure.
  19472. */
  19473. break;
  19474. case XML_SCHEMA_TYPE_GROUP:
  19475. /*
  19476. * URGENT TODO:
  19477. * SPEC src-redefine:
  19478. * (6.2.2) "The {model group} of the model group definition
  19479. * which corresponds to it per XML Representation of Model
  19480. * Group Definition Schema Components (�3.7.2) must be a
  19481. * �valid restriction� of the {model group} of that model
  19482. * group definition in I, as defined in Particle Valid
  19483. * (Restriction) (�3.9.6)."
  19484. */
  19485. break;
  19486. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19487. /*
  19488. * SPEC src-redefine:
  19489. * (7.2.2) "The {attribute uses} and {attribute wildcard} of
  19490. * the attribute group definition which corresponds to it
  19491. * per XML Representation of Attribute Group Definition Schema
  19492. * Components (�3.6.2) must be �valid restrictions� of the
  19493. * {attribute uses} and {attribute wildcard} of that attribute
  19494. * group definition in I, as defined in clause 2, clause 3 and
  19495. * clause 4 of Derivation Valid (Restriction, Complex)
  19496. * (�3.4.6) (where references to the base type definition are
  19497. * understood as references to the attribute group definition
  19498. * in I)."
  19499. */
  19500. err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
  19501. XML_SCHEMA_ACTION_REDEFINE,
  19502. item, redef->target,
  19503. (WXS_ATTR_GROUP_CAST item)->attrUses,
  19504. (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
  19505. (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
  19506. (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
  19507. if (err == -1)
  19508. return(-1);
  19509. break;
  19510. default:
  19511. break;
  19512. }
  19513. redef = redef->next;
  19514. } while (redef != NULL);
  19515. return(0);
  19516. }
  19517. static int
  19518. xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
  19519. xmlSchemaBucketPtr bucket)
  19520. {
  19521. xmlSchemaBasicItemPtr item;
  19522. int err;
  19523. xmlHashTablePtr *table;
  19524. const xmlChar *name;
  19525. int i;
  19526. #define WXS_GET_GLOBAL_HASH(c, slot) { \
  19527. if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
  19528. table = &(WXS_IMPBUCKET((c))->schema->slot); \
  19529. else \
  19530. table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
  19531. /*
  19532. * Add global components to the schema's hash tables.
  19533. * This is the place where duplicate components will be
  19534. * detected.
  19535. * TODO: I think normally we should support imports of the
  19536. * same namespace from multiple locations. We don't do currently,
  19537. * but if we do then according to:
  19538. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
  19539. * we would need, if imported directly, to import redefined
  19540. * components as well to be able to catch clashing components.
  19541. * (I hope I'll still know what this means after some months :-()
  19542. */
  19543. if (bucket == NULL)
  19544. return(-1);
  19545. if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
  19546. return(0);
  19547. bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
  19548. for (i = 0; i < bucket->globals->nbItems; i++) {
  19549. item = bucket->globals->items[i];
  19550. table = NULL;
  19551. switch (item->type) {
  19552. case XML_SCHEMA_TYPE_COMPLEX:
  19553. case XML_SCHEMA_TYPE_SIMPLE:
  19554. if (WXS_REDEFINED_TYPE(item))
  19555. continue;
  19556. name = (WXS_TYPE_CAST item)->name;
  19557. WXS_GET_GLOBAL_HASH(bucket, typeDecl)
  19558. break;
  19559. case XML_SCHEMA_TYPE_ELEMENT:
  19560. name = (WXS_ELEM_CAST item)->name;
  19561. WXS_GET_GLOBAL_HASH(bucket, elemDecl)
  19562. break;
  19563. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19564. name = (WXS_ATTR_CAST item)->name;
  19565. WXS_GET_GLOBAL_HASH(bucket, attrDecl)
  19566. break;
  19567. case XML_SCHEMA_TYPE_GROUP:
  19568. if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
  19569. continue;
  19570. name = (WXS_MODEL_GROUPDEF_CAST item)->name;
  19571. WXS_GET_GLOBAL_HASH(bucket, groupDecl)
  19572. break;
  19573. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19574. if (WXS_REDEFINED_ATTR_GROUP(item))
  19575. continue;
  19576. name = (WXS_ATTR_GROUP_CAST item)->name;
  19577. WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
  19578. break;
  19579. case XML_SCHEMA_TYPE_IDC_KEY:
  19580. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19581. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19582. name = (WXS_IDC_CAST item)->name;
  19583. WXS_GET_GLOBAL_HASH(bucket, idcDef)
  19584. break;
  19585. case XML_SCHEMA_TYPE_NOTATION:
  19586. name = ((xmlSchemaNotationPtr) item)->name;
  19587. WXS_GET_GLOBAL_HASH(bucket, notaDecl)
  19588. break;
  19589. default:
  19590. PERROR_INT("xmlSchemaAddComponents",
  19591. "Unexpected global component type");
  19592. continue;
  19593. }
  19594. if (*table == NULL) {
  19595. *table = xmlHashCreateDict(10, pctxt->dict);
  19596. if (*table == NULL) {
  19597. PERROR_INT("xmlSchemaAddComponents",
  19598. "failed to create a component hash table");
  19599. return(-1);
  19600. }
  19601. }
  19602. err = xmlHashAddEntry(*table, name, item);
  19603. if (err != 0) {
  19604. xmlChar *str = NULL;
  19605. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19606. XML_SCHEMAP_REDEFINED_TYPE,
  19607. WXS_ITEM_NODE(item),
  19608. WXS_BASIC_CAST item,
  19609. "A global %s '%s' does already exist",
  19610. WXS_ITEM_TYPE_NAME(item),
  19611. xmlSchemaGetComponentQName(&str, item));
  19612. FREE_AND_NULL(str);
  19613. }
  19614. }
  19615. /*
  19616. * Process imported/included schemas.
  19617. */
  19618. if (bucket->relations != NULL) {
  19619. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  19620. do {
  19621. if ((rel->bucket != NULL) &&
  19622. ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
  19623. if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
  19624. return(-1);
  19625. }
  19626. rel = rel->next;
  19627. } while (rel != NULL);
  19628. }
  19629. return(0);
  19630. }
  19631. static int
  19632. xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
  19633. xmlSchemaBucketPtr rootBucket)
  19634. {
  19635. xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
  19636. xmlSchemaTreeItemPtr item, *items;
  19637. int nbItems, i, ret = 0;
  19638. xmlSchemaBucketPtr oldbucket = con->bucket;
  19639. xmlSchemaElementPtr elemDecl;
  19640. #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
  19641. if ((con->pending == NULL) ||
  19642. (con->pending->nbItems == 0))
  19643. return(0);
  19644. /*
  19645. * Since xmlSchemaFixupComplexType() will create new particles
  19646. * (local components), and those particle components need a bucket
  19647. * on the constructor, we'll assure here that the constructor has
  19648. * a bucket.
  19649. * TODO: Think about storing locals _only_ on the main bucket.
  19650. */
  19651. if (con->bucket == NULL)
  19652. con->bucket = rootBucket;
  19653. /* TODO:
  19654. * SPEC (src-redefine):
  19655. * (6.2) "If it has no such self-reference, then all of the
  19656. * following must be true:"
  19657. * (6.2.2) The {model group} of the model group definition which
  19658. * corresponds to it per XML Representation of Model Group
  19659. * Definition Schema Components (�3.7.2) must be a �valid
  19660. * restriction� of the {model group} of that model group definition
  19661. * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
  19662. */
  19663. xmlSchemaCheckSRCRedefineFirst(pctxt);
  19664. /*
  19665. * Add global components to the schemata's hash tables.
  19666. */
  19667. xmlSchemaAddComponents(pctxt, rootBucket);
  19668. pctxt->ctxtType = NULL;
  19669. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19670. nbItems = con->pending->nbItems;
  19671. /*
  19672. * Now that we have parsed *all* the schema document(s) and converted
  19673. * them to schema components, we can resolve references, apply component
  19674. * constraints, create the FSA from the content model, etc.
  19675. */
  19676. /*
  19677. * Resolve references of..
  19678. *
  19679. * 1. element declarations:
  19680. * - the type definition
  19681. * - the substitution group affiliation
  19682. * 2. simple/complex types:
  19683. * - the base type definition
  19684. * - the memberTypes of union types
  19685. * - the itemType of list types
  19686. * 3. attributes declarations and attribute uses:
  19687. * - the type definition
  19688. * - if an attribute use, then the attribute declaration
  19689. * 4. attribute group references:
  19690. * - the attribute group definition
  19691. * 5. particles:
  19692. * - the term of the particle (e.g. a model group)
  19693. * 6. IDC key-references:
  19694. * - the referenced IDC 'key' or 'unique' definition
  19695. * 7. Attribute prohibitions which had a "ref" attribute.
  19696. */
  19697. for (i = 0; i < nbItems; i++) {
  19698. item = items[i];
  19699. switch (item->type) {
  19700. case XML_SCHEMA_TYPE_ELEMENT:
  19701. xmlSchemaResolveElementReferences(
  19702. (xmlSchemaElementPtr) item, pctxt);
  19703. FIXHFAILURE;
  19704. break;
  19705. case XML_SCHEMA_TYPE_COMPLEX:
  19706. case XML_SCHEMA_TYPE_SIMPLE:
  19707. xmlSchemaResolveTypeReferences(
  19708. (xmlSchemaTypePtr) item, pctxt);
  19709. FIXHFAILURE;
  19710. break;
  19711. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19712. xmlSchemaResolveAttrTypeReferences(
  19713. (xmlSchemaAttributePtr) item, pctxt);
  19714. FIXHFAILURE;
  19715. break;
  19716. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19717. xmlSchemaResolveAttrUseReferences(
  19718. (xmlSchemaAttributeUsePtr) item, pctxt);
  19719. FIXHFAILURE;
  19720. break;
  19721. case XML_SCHEMA_EXTRA_QNAMEREF:
  19722. if ((WXS_QNAME_CAST item)->itemType ==
  19723. XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
  19724. {
  19725. xmlSchemaResolveAttrGroupReferences(
  19726. WXS_QNAME_CAST item, pctxt);
  19727. }
  19728. FIXHFAILURE;
  19729. break;
  19730. case XML_SCHEMA_TYPE_SEQUENCE:
  19731. case XML_SCHEMA_TYPE_CHOICE:
  19732. case XML_SCHEMA_TYPE_ALL:
  19733. xmlSchemaResolveModelGroupParticleReferences(pctxt,
  19734. WXS_MODEL_GROUP_CAST item);
  19735. FIXHFAILURE;
  19736. break;
  19737. case XML_SCHEMA_TYPE_IDC_KEY:
  19738. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19739. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19740. xmlSchemaResolveIDCKeyReferences(
  19741. (xmlSchemaIDCPtr) item, pctxt);
  19742. FIXHFAILURE;
  19743. break;
  19744. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  19745. /*
  19746. * Handle attribue prohibition which had a
  19747. * "ref" attribute.
  19748. */
  19749. xmlSchemaResolveAttrUseProhibReferences(
  19750. WXS_ATTR_PROHIB_CAST item, pctxt);
  19751. FIXHFAILURE;
  19752. break;
  19753. default:
  19754. break;
  19755. }
  19756. }
  19757. if (pctxt->nberrors != 0)
  19758. goto exit_error;
  19759. /*
  19760. * Now that all references are resolved we
  19761. * can check for circularity of...
  19762. * 1. the base axis of type definitions
  19763. * 2. nested model group definitions
  19764. * 3. nested attribute group definitions
  19765. * TODO: check for circual substitution groups.
  19766. */
  19767. for (i = 0; i < nbItems; i++) {
  19768. item = items[i];
  19769. /*
  19770. * Let's better stop on the first error here.
  19771. */
  19772. switch (item->type) {
  19773. case XML_SCHEMA_TYPE_COMPLEX:
  19774. case XML_SCHEMA_TYPE_SIMPLE:
  19775. xmlSchemaCheckTypeDefCircular(
  19776. (xmlSchemaTypePtr) item, pctxt);
  19777. FIXHFAILURE;
  19778. if (pctxt->nberrors != 0)
  19779. goto exit_error;
  19780. break;
  19781. case XML_SCHEMA_TYPE_GROUP:
  19782. xmlSchemaCheckGroupDefCircular(
  19783. (xmlSchemaModelGroupDefPtr) item, pctxt);
  19784. FIXHFAILURE;
  19785. if (pctxt->nberrors != 0)
  19786. goto exit_error;
  19787. break;
  19788. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19789. xmlSchemaCheckAttrGroupCircular(
  19790. (xmlSchemaAttributeGroupPtr) item, pctxt);
  19791. FIXHFAILURE;
  19792. if (pctxt->nberrors != 0)
  19793. goto exit_error;
  19794. break;
  19795. default:
  19796. break;
  19797. }
  19798. }
  19799. if (pctxt->nberrors != 0)
  19800. goto exit_error;
  19801. /*
  19802. * Model group definition references:
  19803. * Such a reference is reflected by a particle at the component
  19804. * level. Until now the 'term' of such particles pointed
  19805. * to the model group definition; this was done, in order to
  19806. * ease circularity checks. Now we need to set the 'term' of
  19807. * such particles to the model group of the model group definition.
  19808. */
  19809. for (i = 0; i < nbItems; i++) {
  19810. item = items[i];
  19811. switch (item->type) {
  19812. case XML_SCHEMA_TYPE_SEQUENCE:
  19813. case XML_SCHEMA_TYPE_CHOICE:
  19814. xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
  19815. WXS_MODEL_GROUP_CAST item);
  19816. break;
  19817. default:
  19818. break;
  19819. }
  19820. }
  19821. if (pctxt->nberrors != 0)
  19822. goto exit_error;
  19823. /*
  19824. * Expand attribute group references of attribute group definitions.
  19825. */
  19826. for (i = 0; i < nbItems; i++) {
  19827. item = items[i];
  19828. switch (item->type) {
  19829. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19830. if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
  19831. WXS_ATTR_GROUP_HAS_REFS(item))
  19832. {
  19833. xmlSchemaAttributeGroupExpandRefs(pctxt,
  19834. WXS_ATTR_GROUP_CAST item);
  19835. FIXHFAILURE;
  19836. }
  19837. break;
  19838. default:
  19839. break;
  19840. }
  19841. }
  19842. if (pctxt->nberrors != 0)
  19843. goto exit_error;
  19844. /*
  19845. * First compute the variety of simple types. This is needed as
  19846. * a seperate step, since otherwise we won't be able to detect
  19847. * circular union types in all cases.
  19848. */
  19849. for (i = 0; i < nbItems; i++) {
  19850. item = items[i];
  19851. switch (item->type) {
  19852. case XML_SCHEMA_TYPE_SIMPLE:
  19853. if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
  19854. xmlSchemaFixupSimpleTypeStageOne(pctxt,
  19855. (xmlSchemaTypePtr) item);
  19856. FIXHFAILURE;
  19857. }
  19858. break;
  19859. default:
  19860. break;
  19861. }
  19862. }
  19863. if (pctxt->nberrors != 0)
  19864. goto exit_error;
  19865. /*
  19866. * Detect circular union types. Note that this needs the variety to
  19867. * be already computed.
  19868. */
  19869. for (i = 0; i < nbItems; i++) {
  19870. item = items[i];
  19871. switch (item->type) {
  19872. case XML_SCHEMA_TYPE_SIMPLE:
  19873. if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
  19874. xmlSchemaCheckUnionTypeDefCircular(pctxt,
  19875. (xmlSchemaTypePtr) item);
  19876. FIXHFAILURE;
  19877. }
  19878. break;
  19879. default:
  19880. break;
  19881. }
  19882. }
  19883. if (pctxt->nberrors != 0)
  19884. goto exit_error;
  19885. /*
  19886. * Do the complete type fixup for simple types.
  19887. */
  19888. for (i = 0; i < nbItems; i++) {
  19889. item = items[i];
  19890. switch (item->type) {
  19891. case XML_SCHEMA_TYPE_SIMPLE:
  19892. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  19893. xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
  19894. FIXHFAILURE;
  19895. }
  19896. break;
  19897. default:
  19898. break;
  19899. }
  19900. }
  19901. if (pctxt->nberrors != 0)
  19902. goto exit_error;
  19903. /*
  19904. * At this point we need build and check all simple types.
  19905. */
  19906. /*
  19907. * Apply contraints for attribute declarations.
  19908. */
  19909. for (i = 0; i < nbItems; i++) {
  19910. item = items[i];
  19911. switch (item->type) {
  19912. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19913. xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
  19914. FIXHFAILURE;
  19915. break;
  19916. default:
  19917. break;
  19918. }
  19919. }
  19920. if (pctxt->nberrors != 0)
  19921. goto exit_error;
  19922. /*
  19923. * Apply constraints for attribute uses.
  19924. */
  19925. for (i = 0; i < nbItems; i++) {
  19926. item = items[i];
  19927. switch (item->type) {
  19928. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19929. if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
  19930. xmlSchemaCheckAttrUsePropsCorrect(pctxt,
  19931. WXS_ATTR_USE_CAST item);
  19932. FIXHFAILURE;
  19933. }
  19934. break;
  19935. default:
  19936. break;
  19937. }
  19938. }
  19939. if (pctxt->nberrors != 0)
  19940. goto exit_error;
  19941. /*
  19942. * Apply constraints for attribute group definitions.
  19943. */
  19944. for (i = 0; i < nbItems; i++) {
  19945. item = items[i];
  19946. switch (item->type) {
  19947. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19948. if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
  19949. ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
  19950. {
  19951. xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
  19952. FIXHFAILURE;
  19953. }
  19954. break;
  19955. default:
  19956. break;
  19957. }
  19958. }
  19959. if (pctxt->nberrors != 0)
  19960. goto exit_error;
  19961. /*
  19962. * Apply constraints for redefinitions.
  19963. */
  19964. if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
  19965. xmlSchemaCheckSRCRedefineSecond(pctxt);
  19966. if (pctxt->nberrors != 0)
  19967. goto exit_error;
  19968. /*
  19969. * Complex types are builded and checked.
  19970. */
  19971. for (i = 0; i < nbItems; i++) {
  19972. item = con->pending->items[i];
  19973. switch (item->type) {
  19974. case XML_SCHEMA_TYPE_COMPLEX:
  19975. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  19976. xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
  19977. FIXHFAILURE;
  19978. }
  19979. break;
  19980. default:
  19981. break;
  19982. }
  19983. }
  19984. if (pctxt->nberrors != 0)
  19985. goto exit_error;
  19986. /*
  19987. * The list could have changed, since xmlSchemaFixupComplexType()
  19988. * will create particles and model groups in some cases.
  19989. */
  19990. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19991. nbItems = con->pending->nbItems;
  19992. /*
  19993. * Apply some constraints for element declarations.
  19994. */
  19995. for (i = 0; i < nbItems; i++) {
  19996. item = items[i];
  19997. switch (item->type) {
  19998. case XML_SCHEMA_TYPE_ELEMENT:
  19999. elemDecl = (xmlSchemaElementPtr) item;
  20000. if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
  20001. {
  20002. xmlSchemaCheckElementDeclComponent(
  20003. (xmlSchemaElementPtr) elemDecl, pctxt);
  20004. FIXHFAILURE;
  20005. }
  20006. #ifdef WXS_ELEM_DECL_CONS_ENABLED
  20007. /*
  20008. * Schema Component Constraint: Element Declarations Consistent
  20009. * Apply this constraint to local types of element declarations.
  20010. */
  20011. if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
  20012. (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
  20013. (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
  20014. {
  20015. xmlSchemaCheckElementDeclConsistent(pctxt,
  20016. WXS_BASIC_CAST elemDecl,
  20017. WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
  20018. NULL, NULL, 0);
  20019. }
  20020. #endif
  20021. break;
  20022. default:
  20023. break;
  20024. }
  20025. }
  20026. if (pctxt->nberrors != 0)
  20027. goto exit_error;
  20028. /*
  20029. * Finally we can build the automaton from the content model of
  20030. * complex types.
  20031. */
  20032. for (i = 0; i < nbItems; i++) {
  20033. item = items[i];
  20034. switch (item->type) {
  20035. case XML_SCHEMA_TYPE_COMPLEX:
  20036. xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
  20037. /* FIXHFAILURE; */
  20038. break;
  20039. default:
  20040. break;
  20041. }
  20042. }
  20043. if (pctxt->nberrors != 0)
  20044. goto exit_error;
  20045. /*
  20046. * URGENT TODO: cos-element-consistent
  20047. */
  20048. goto exit;
  20049. exit_error:
  20050. ret = pctxt->err;
  20051. goto exit;
  20052. exit_failure:
  20053. ret = -1;
  20054. exit:
  20055. /*
  20056. * Reset the constructor. This is needed for XSI acquisition, since
  20057. * those items will be processed over and over again for every XSI
  20058. * if not cleared here.
  20059. */
  20060. con->bucket = oldbucket;
  20061. con->pending->nbItems = 0;
  20062. if (con->substGroups != NULL) {
  20063. xmlHashFree(con->substGroups,
  20064. (xmlHashDeallocator) xmlSchemaSubstGroupFree);
  20065. con->substGroups = NULL;
  20066. }
  20067. if (con->redefs != NULL) {
  20068. xmlSchemaRedefListFree(con->redefs);
  20069. con->redefs = NULL;
  20070. }
  20071. return(ret);
  20072. }
  20073. /**
  20074. * xmlSchemaParse:
  20075. * @ctxt: a schema validation context
  20076. *
  20077. * parse a schema definition resource and build an internal
  20078. * XML Shema struture which can be used to validate instances.
  20079. *
  20080. * Returns the internal XML Schema structure built from the resource or
  20081. * NULL in case of error
  20082. */
  20083. xmlSchemaPtr
  20084. xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
  20085. {
  20086. xmlSchemaPtr mainSchema = NULL;
  20087. xmlSchemaBucketPtr bucket = NULL;
  20088. int res;
  20089. /*
  20090. * This one is used if the schema to be parsed was specified via
  20091. * the API; i.e. not automatically by the validated instance document.
  20092. */
  20093. xmlSchemaInitTypes();
  20094. if (ctxt == NULL)
  20095. return (NULL);
  20096. /* TODO: Init the context. Is this all we need?*/
  20097. ctxt->nberrors = 0;
  20098. ctxt->err = 0;
  20099. ctxt->counter = 0;
  20100. /* Create the *main* schema. */
  20101. mainSchema = xmlSchemaNewSchema(ctxt);
  20102. if (mainSchema == NULL)
  20103. goto exit_failure;
  20104. /*
  20105. * Create the schema constructor.
  20106. */
  20107. if (ctxt->constructor == NULL) {
  20108. ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
  20109. if (ctxt->constructor == NULL)
  20110. return(NULL);
  20111. /* Take ownership of the constructor to be able to free it. */
  20112. ctxt->ownsConstructor = 1;
  20113. }
  20114. ctxt->constructor->mainSchema = mainSchema;
  20115. /*
  20116. * Locate and add the schema document.
  20117. */
  20118. res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
  20119. ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
  20120. NULL, NULL, &bucket);
  20121. if (res == -1)
  20122. goto exit_failure;
  20123. if (res != 0)
  20124. goto exit;
  20125. if (bucket == NULL) {
  20126. /* TODO: Error code, actually we failed to *locate* the schema. */
  20127. if (ctxt->URL)
  20128. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20129. NULL, NULL,
  20130. "Failed to locate the main schema resource at '%s'",
  20131. ctxt->URL, NULL);
  20132. else
  20133. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20134. NULL, NULL,
  20135. "Failed to locate the main schema resource",
  20136. NULL, NULL);
  20137. goto exit;
  20138. }
  20139. /* Then do the parsing for good. */
  20140. if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
  20141. goto exit_failure;
  20142. if (ctxt->nberrors != 0)
  20143. goto exit;
  20144. mainSchema->doc = bucket->doc;
  20145. mainSchema->preserve = ctxt->preserve;
  20146. ctxt->schema = mainSchema;
  20147. if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
  20148. goto exit_failure;
  20149. /*
  20150. * TODO: This is not nice, since we cannot distinguish from the
  20151. * result if there was an internal error or not.
  20152. */
  20153. exit:
  20154. if (ctxt->nberrors != 0) {
  20155. if (mainSchema) {
  20156. xmlSchemaFree(mainSchema);
  20157. mainSchema = NULL;
  20158. }
  20159. if (ctxt->constructor) {
  20160. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20161. ctxt->constructor = NULL;
  20162. ctxt->ownsConstructor = 0;
  20163. }
  20164. }
  20165. ctxt->schema = NULL;
  20166. return(mainSchema);
  20167. exit_failure:
  20168. /*
  20169. * Quite verbose, but should catch internal errors, which were
  20170. * not communitated.
  20171. */
  20172. if (mainSchema) {
  20173. xmlSchemaFree(mainSchema);
  20174. mainSchema = NULL;
  20175. }
  20176. if (ctxt->constructor) {
  20177. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20178. ctxt->constructor = NULL;
  20179. ctxt->ownsConstructor = 0;
  20180. }
  20181. PERROR_INT2("xmlSchemaParse",
  20182. "An internal error occured");
  20183. ctxt->schema = NULL;
  20184. return(NULL);
  20185. }
  20186. /**
  20187. * xmlSchemaSetParserErrors:
  20188. * @ctxt: a schema validation context
  20189. * @err: the error callback
  20190. * @warn: the warning callback
  20191. * @ctx: contextual data for the callbacks
  20192. *
  20193. * Set the callback functions used to handle errors for a validation context
  20194. */
  20195. void
  20196. xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20197. xmlSchemaValidityErrorFunc err,
  20198. xmlSchemaValidityWarningFunc warn, void *ctx)
  20199. {
  20200. if (ctxt == NULL)
  20201. return;
  20202. ctxt->error = err;
  20203. ctxt->warning = warn;
  20204. ctxt->errCtxt = ctx;
  20205. if (ctxt->vctxt != NULL)
  20206. xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
  20207. }
  20208. /**
  20209. * xmlSchemaSetParserStructuredErrors:
  20210. * @ctxt: a schema parser context
  20211. * @serror: the structured error function
  20212. * @ctx: the functions context
  20213. *
  20214. * Set the structured error callback
  20215. */
  20216. void
  20217. xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
  20218. xmlStructuredErrorFunc serror,
  20219. void *ctx)
  20220. {
  20221. if (ctxt == NULL)
  20222. return;
  20223. ctxt->serror = serror;
  20224. ctxt->errCtxt = ctx;
  20225. if (ctxt->vctxt != NULL)
  20226. xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
  20227. }
  20228. /**
  20229. * xmlSchemaGetParserErrors:
  20230. * @ctxt: a XMl-Schema parser context
  20231. * @err: the error callback result
  20232. * @warn: the warning callback result
  20233. * @ctx: contextual data for the callbacks result
  20234. *
  20235. * Get the callback information used to handle errors for a parser context
  20236. *
  20237. * Returns -1 in case of failure, 0 otherwise
  20238. */
  20239. int
  20240. xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20241. xmlSchemaValidityErrorFunc * err,
  20242. xmlSchemaValidityWarningFunc * warn, void **ctx)
  20243. {
  20244. if (ctxt == NULL)
  20245. return(-1);
  20246. if (err != NULL)
  20247. *err = ctxt->error;
  20248. if (warn != NULL)
  20249. *warn = ctxt->warning;
  20250. if (ctx != NULL)
  20251. *ctx = ctxt->errCtxt;
  20252. return(0);
  20253. }
  20254. /**
  20255. * xmlSchemaFacetTypeToString:
  20256. * @type: the facet type
  20257. *
  20258. * Convert the xmlSchemaTypeType to a char string.
  20259. *
  20260. * Returns the char string representation of the facet type if the
  20261. * type is a facet and an "Internal Error" string otherwise.
  20262. */
  20263. static const xmlChar *
  20264. xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
  20265. {
  20266. switch (type) {
  20267. case XML_SCHEMA_FACET_PATTERN:
  20268. return (BAD_CAST "pattern");
  20269. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  20270. return (BAD_CAST "maxExclusive");
  20271. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  20272. return (BAD_CAST "maxInclusive");
  20273. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  20274. return (BAD_CAST "minExclusive");
  20275. case XML_SCHEMA_FACET_MININCLUSIVE:
  20276. return (BAD_CAST "minInclusive");
  20277. case XML_SCHEMA_FACET_WHITESPACE:
  20278. return (BAD_CAST "whiteSpace");
  20279. case XML_SCHEMA_FACET_ENUMERATION:
  20280. return (BAD_CAST "enumeration");
  20281. case XML_SCHEMA_FACET_LENGTH:
  20282. return (BAD_CAST "length");
  20283. case XML_SCHEMA_FACET_MAXLENGTH:
  20284. return (BAD_CAST "maxLength");
  20285. case XML_SCHEMA_FACET_MINLENGTH:
  20286. return (BAD_CAST "minLength");
  20287. case XML_SCHEMA_FACET_TOTALDIGITS:
  20288. return (BAD_CAST "totalDigits");
  20289. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  20290. return (BAD_CAST "fractionDigits");
  20291. default:
  20292. break;
  20293. }
  20294. return (BAD_CAST "Internal Error");
  20295. }
  20296. static xmlSchemaWhitespaceValueType
  20297. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
  20298. {
  20299. /*
  20300. * The normalization type can be changed only for types which are derived
  20301. * from xsd:string.
  20302. */
  20303. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  20304. /*
  20305. * Note that we assume a whitespace of preserve for anySimpleType.
  20306. */
  20307. if ((type->builtInType == XML_SCHEMAS_STRING) ||
  20308. (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  20309. return(XML_SCHEMA_WHITESPACE_PRESERVE);
  20310. else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
  20311. return(XML_SCHEMA_WHITESPACE_REPLACE);
  20312. else {
  20313. /*
  20314. * For all �atomic� datatypes other than string (and types �derived�
  20315. * by �restriction� from it) the value of whiteSpace is fixed to
  20316. * collapse
  20317. * Note that this includes built-in list datatypes.
  20318. */
  20319. return(XML_SCHEMA_WHITESPACE_COLLAPSE);
  20320. }
  20321. } else if (WXS_IS_LIST(type)) {
  20322. /*
  20323. * For list types the facet "whiteSpace" is fixed to "collapse".
  20324. */
  20325. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20326. } else if (WXS_IS_UNION(type)) {
  20327. return (XML_SCHEMA_WHITESPACE_UNKNOWN);
  20328. } else if (WXS_IS_ATOMIC(type)) {
  20329. if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
  20330. return (XML_SCHEMA_WHITESPACE_PRESERVE);
  20331. else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
  20332. return (XML_SCHEMA_WHITESPACE_REPLACE);
  20333. else
  20334. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20335. }
  20336. return (-1);
  20337. }
  20338. /************************************************************************
  20339. * *
  20340. * Simple type validation *
  20341. * *
  20342. ************************************************************************/
  20343. /************************************************************************
  20344. * *
  20345. * DOM Validation code *
  20346. * *
  20347. ************************************************************************/
  20348. /**
  20349. * xmlSchemaAssembleByLocation:
  20350. * @pctxt: a schema parser context
  20351. * @vctxt: a schema validation context
  20352. * @schema: the existing schema
  20353. * @node: the node that fired the assembling
  20354. * @nsName: the namespace name of the new schema
  20355. * @location: the location of the schema
  20356. *
  20357. * Expands an existing schema by an additional schema.
  20358. *
  20359. * Returns 0 if the new schema is correct, a positive error code
  20360. * number otherwise and -1 in case of an internal or API error.
  20361. */
  20362. static int
  20363. xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
  20364. xmlSchemaPtr schema,
  20365. xmlNodePtr node,
  20366. const xmlChar *nsName,
  20367. const xmlChar *location)
  20368. {
  20369. int ret = 0;
  20370. xmlSchemaParserCtxtPtr pctxt;
  20371. xmlSchemaBucketPtr bucket = NULL;
  20372. if ((vctxt == NULL) || (schema == NULL))
  20373. return (-1);
  20374. if (vctxt->pctxt == NULL) {
  20375. VERROR_INT("xmlSchemaAssembleByLocation",
  20376. "no parser context available");
  20377. return(-1);
  20378. }
  20379. pctxt = vctxt->pctxt;
  20380. if (pctxt->constructor == NULL) {
  20381. PERROR_INT("xmlSchemaAssembleByLocation",
  20382. "no constructor");
  20383. return(-1);
  20384. }
  20385. /*
  20386. * Acquire the schema document.
  20387. */
  20388. location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  20389. location, node);
  20390. /*
  20391. * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
  20392. * the process will automatically change this to
  20393. * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
  20394. */
  20395. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  20396. location, NULL, NULL, 0, node, NULL, nsName,
  20397. &bucket);
  20398. if (ret != 0)
  20399. return(ret);
  20400. if (bucket == NULL) {
  20401. /*
  20402. * Generate a warning that the document could not be located.
  20403. */
  20404. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20405. node, NULL,
  20406. "The document at location '%s' could not be acquired",
  20407. location, NULL, NULL);
  20408. return(ret);
  20409. }
  20410. /*
  20411. * The first located schema will be handled as if all other
  20412. * schemas imported by XSI were imported by this first schema.
  20413. */
  20414. if ((bucket != NULL) &&
  20415. (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
  20416. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  20417. /*
  20418. * TODO: Is this handled like an import? I.e. is it not an error
  20419. * if the schema cannot be located?
  20420. */
  20421. if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
  20422. return(0);
  20423. /*
  20424. * We will reuse the parser context for every schema imported
  20425. * directly via XSI. So reset the context.
  20426. */
  20427. pctxt->nberrors = 0;
  20428. pctxt->err = 0;
  20429. pctxt->doc = bucket->doc;
  20430. ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
  20431. if (ret == -1) {
  20432. pctxt->doc = NULL;
  20433. goto exit_failure;
  20434. }
  20435. /* Paranoid error channelling. */
  20436. if ((ret == 0) && (pctxt->nberrors != 0))
  20437. ret = pctxt->err;
  20438. if (pctxt->nberrors == 0) {
  20439. /*
  20440. * Only bother to fixup pending components, if there was
  20441. * no error yet.
  20442. * For every XSI acquired schema (and its sub-schemata) we will
  20443. * fixup the components.
  20444. */
  20445. xmlSchemaFixupComponents(pctxt, bucket);
  20446. ret = pctxt->err;
  20447. /*
  20448. * Not nice, but we need somehow to channel the schema parser
  20449. * error to the validation context.
  20450. */
  20451. if ((ret != 0) && (vctxt->err == 0))
  20452. vctxt->err = ret;
  20453. vctxt->nberrors += pctxt->nberrors;
  20454. } else {
  20455. /* Add to validation error sum. */
  20456. vctxt->nberrors += pctxt->nberrors;
  20457. }
  20458. pctxt->doc = NULL;
  20459. return(ret);
  20460. exit_failure:
  20461. pctxt->doc = NULL;
  20462. return (-1);
  20463. }
  20464. static xmlSchemaAttrInfoPtr
  20465. xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
  20466. int metaType)
  20467. {
  20468. if (vctxt->nbAttrInfos == 0)
  20469. return (NULL);
  20470. {
  20471. int i;
  20472. xmlSchemaAttrInfoPtr iattr;
  20473. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  20474. iattr = vctxt->attrInfos[i];
  20475. if (iattr->metaType == metaType)
  20476. return (iattr);
  20477. }
  20478. }
  20479. return (NULL);
  20480. }
  20481. /**
  20482. * xmlSchemaAssembleByXSI:
  20483. * @vctxt: a schema validation context
  20484. *
  20485. * Expands an existing schema by an additional schema using
  20486. * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
  20487. * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
  20488. * must be set to 1.
  20489. *
  20490. * Returns 0 if the new schema is correct, a positive error code
  20491. * number otherwise and -1 in case of an internal or API error.
  20492. */
  20493. static int
  20494. xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
  20495. {
  20496. const xmlChar *cur, *end;
  20497. const xmlChar *nsname = NULL, *location;
  20498. int count = 0;
  20499. int ret = 0;
  20500. xmlSchemaAttrInfoPtr iattr;
  20501. /*
  20502. * Parse the value; we will assume an even number of values
  20503. * to be given (this is how Xerces and XSV work).
  20504. *
  20505. * URGENT TODO: !! This needs to work for both
  20506. * @noNamespaceSchemaLocation AND @schemaLocation on the same
  20507. * element !!
  20508. */
  20509. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20510. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
  20511. if (iattr == NULL)
  20512. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20513. XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
  20514. if (iattr == NULL)
  20515. return (0);
  20516. cur = iattr->value;
  20517. do {
  20518. /*
  20519. * TODO: Move the string parsing mechanism away from here.
  20520. */
  20521. if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
  20522. /*
  20523. * Get the namespace name.
  20524. */
  20525. while (IS_BLANK_CH(*cur))
  20526. cur++;
  20527. end = cur;
  20528. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20529. end++;
  20530. if (end == cur)
  20531. break;
  20532. count++; /* TODO: Don't use the schema's dict. */
  20533. nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20534. cur = end;
  20535. }
  20536. /*
  20537. * Get the URI.
  20538. */
  20539. while (IS_BLANK_CH(*cur))
  20540. cur++;
  20541. end = cur;
  20542. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20543. end++;
  20544. if (end == cur) {
  20545. if (iattr->metaType ==
  20546. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
  20547. {
  20548. /*
  20549. * If using @schemaLocation then tuples are expected.
  20550. * I.e. the namespace name *and* the document's URI.
  20551. */
  20552. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20553. iattr->node, NULL,
  20554. "The value must consist of tuples: the target namespace "
  20555. "name and the document's URI", NULL, NULL, NULL);
  20556. }
  20557. break;
  20558. }
  20559. count++; /* TODO: Don't use the schema's dict. */
  20560. location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20561. cur = end;
  20562. ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
  20563. iattr->node, nsname, location);
  20564. if (ret == -1) {
  20565. VERROR_INT("xmlSchemaAssembleByXSI",
  20566. "assembling schemata");
  20567. return (-1);
  20568. }
  20569. } while (*cur != 0);
  20570. return (ret);
  20571. }
  20572. static const xmlChar *
  20573. xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
  20574. const xmlChar *prefix)
  20575. {
  20576. if (vctxt->sax != NULL) {
  20577. int i, j;
  20578. xmlSchemaNodeInfoPtr inode;
  20579. for (i = vctxt->depth; i >= 0; i--) {
  20580. if (vctxt->elemInfos[i]->nbNsBindings != 0) {
  20581. inode = vctxt->elemInfos[i];
  20582. for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
  20583. if (((prefix == NULL) &&
  20584. (inode->nsBindings[j] == NULL)) ||
  20585. ((prefix != NULL) && xmlStrEqual(prefix,
  20586. inode->nsBindings[j]))) {
  20587. /*
  20588. * Note that the namespace bindings are already
  20589. * in a string dict.
  20590. */
  20591. return (inode->nsBindings[j+1]);
  20592. }
  20593. }
  20594. }
  20595. }
  20596. return (NULL);
  20597. #ifdef LIBXML_READER_ENABLED
  20598. } else if (vctxt->reader != NULL) {
  20599. xmlChar *nsName;
  20600. nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
  20601. if (nsName != NULL) {
  20602. const xmlChar *ret;
  20603. ret = xmlDictLookup(vctxt->dict, nsName, -1);
  20604. xmlFree(nsName);
  20605. return (ret);
  20606. } else
  20607. return (NULL);
  20608. #endif
  20609. } else {
  20610. xmlNsPtr ns;
  20611. if ((vctxt->inode->node == NULL) ||
  20612. (vctxt->inode->node->doc == NULL)) {
  20613. VERROR_INT("xmlSchemaLookupNamespace",
  20614. "no node or node's doc avaliable");
  20615. return (NULL);
  20616. }
  20617. ns = xmlSearchNs(vctxt->inode->node->doc,
  20618. vctxt->inode->node, prefix);
  20619. if (ns != NULL)
  20620. return (ns->href);
  20621. return (NULL);
  20622. }
  20623. }
  20624. /*
  20625. * This one works on the schema of the validation context.
  20626. */
  20627. static int
  20628. xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
  20629. xmlSchemaPtr schema,
  20630. xmlNodePtr node,
  20631. const xmlChar *value,
  20632. xmlSchemaValPtr *val,
  20633. int valNeeded)
  20634. {
  20635. int ret;
  20636. if (vctxt && (vctxt->schema == NULL)) {
  20637. VERROR_INT("xmlSchemaValidateNotation",
  20638. "a schema is needed on the validation context");
  20639. return (-1);
  20640. }
  20641. ret = xmlValidateQName(value, 1);
  20642. if (ret != 0)
  20643. return (ret);
  20644. {
  20645. xmlChar *localName = NULL;
  20646. xmlChar *prefix = NULL;
  20647. localName = xmlSplitQName2(value, &prefix);
  20648. if (prefix != NULL) {
  20649. const xmlChar *nsName = NULL;
  20650. if (vctxt != NULL)
  20651. nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
  20652. else if (node != NULL) {
  20653. xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
  20654. if (ns != NULL)
  20655. nsName = ns->href;
  20656. } else {
  20657. xmlFree(prefix);
  20658. xmlFree(localName);
  20659. return (1);
  20660. }
  20661. if (nsName == NULL) {
  20662. xmlFree(prefix);
  20663. xmlFree(localName);
  20664. return (1);
  20665. }
  20666. if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
  20667. if ((valNeeded) && (val != NULL)) {
  20668. (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
  20669. xmlStrdup(nsName));
  20670. if (*val == NULL)
  20671. ret = -1;
  20672. }
  20673. } else
  20674. ret = 1;
  20675. xmlFree(prefix);
  20676. xmlFree(localName);
  20677. } else {
  20678. if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
  20679. if (valNeeded && (val != NULL)) {
  20680. (*val) = xmlSchemaNewNOTATIONValue(
  20681. BAD_CAST xmlStrdup(value), NULL);
  20682. if (*val == NULL)
  20683. ret = -1;
  20684. }
  20685. } else
  20686. return (1);
  20687. }
  20688. }
  20689. return (ret);
  20690. }
  20691. static int
  20692. xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
  20693. const xmlChar* lname,
  20694. const xmlChar* nsname)
  20695. {
  20696. int i;
  20697. lname = xmlDictLookup(vctxt->dict, lname, -1);
  20698. if (lname == NULL)
  20699. return(-1);
  20700. if (nsname != NULL) {
  20701. nsname = xmlDictLookup(vctxt->dict, nsname, -1);
  20702. if (nsname == NULL)
  20703. return(-1);
  20704. }
  20705. for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
  20706. if ((vctxt->nodeQNames->items [i] == lname) &&
  20707. (vctxt->nodeQNames->items[i +1] == nsname))
  20708. /* Already there */
  20709. return(i);
  20710. }
  20711. /* Add new entry. */
  20712. i = vctxt->nodeQNames->nbItems;
  20713. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
  20714. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
  20715. return(i);
  20716. }
  20717. /************************************************************************
  20718. * *
  20719. * Validation of identity-constraints (IDC) *
  20720. * *
  20721. ************************************************************************/
  20722. /**
  20723. * xmlSchemaAugmentIDC:
  20724. * @idcDef: the IDC definition
  20725. *
  20726. * Creates an augmented IDC definition item.
  20727. *
  20728. * Returns the item, or NULL on internal errors.
  20729. */
  20730. static void
  20731. xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
  20732. xmlSchemaValidCtxtPtr vctxt)
  20733. {
  20734. xmlSchemaIDCAugPtr aidc;
  20735. aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
  20736. if (aidc == NULL) {
  20737. xmlSchemaVErrMemory(vctxt,
  20738. "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
  20739. NULL);
  20740. return;
  20741. }
  20742. aidc->keyrefDepth = -1;
  20743. aidc->def = idcDef;
  20744. aidc->next = NULL;
  20745. if (vctxt->aidcs == NULL)
  20746. vctxt->aidcs = aidc;
  20747. else {
  20748. aidc->next = vctxt->aidcs;
  20749. vctxt->aidcs = aidc;
  20750. }
  20751. /*
  20752. * Save if we have keyrefs at all.
  20753. */
  20754. if ((vctxt->hasKeyrefs == 0) &&
  20755. (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
  20756. vctxt->hasKeyrefs = 1;
  20757. }
  20758. /**
  20759. * xmlSchemaAugmentImportedIDC:
  20760. * @imported: the imported schema
  20761. *
  20762. * Creates an augmented IDC definition for the imported schema.
  20763. */
  20764. static void
  20765. xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
  20766. if (imported->schema->idcDef != NULL) {
  20767. xmlHashScan(imported->schema->idcDef ,
  20768. (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
  20769. }
  20770. }
  20771. /**
  20772. * xmlSchemaIDCNewBinding:
  20773. * @idcDef: the IDC definition of this binding
  20774. *
  20775. * Creates a new IDC binding.
  20776. *
  20777. * Returns the new IDC binding, NULL on internal errors.
  20778. */
  20779. static xmlSchemaPSVIIDCBindingPtr
  20780. xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
  20781. {
  20782. xmlSchemaPSVIIDCBindingPtr ret;
  20783. ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
  20784. sizeof(xmlSchemaPSVIIDCBinding));
  20785. if (ret == NULL) {
  20786. xmlSchemaVErrMemory(NULL,
  20787. "allocating a PSVI IDC binding item", NULL);
  20788. return (NULL);
  20789. }
  20790. memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
  20791. ret->definition = idcDef;
  20792. return (ret);
  20793. }
  20794. /**
  20795. * xmlSchemaIDCStoreNodeTableItem:
  20796. * @vctxt: the WXS validation context
  20797. * @item: the IDC node table item
  20798. *
  20799. * The validation context is used to store IDC node table items.
  20800. * They are stored to avoid copying them if IDC node-tables are merged
  20801. * with corresponding parent IDC node-tables (bubbling).
  20802. *
  20803. * Returns 0 if succeeded, -1 on internal errors.
  20804. */
  20805. static int
  20806. xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
  20807. xmlSchemaPSVIIDCNodePtr item)
  20808. {
  20809. /*
  20810. * Add to gobal list.
  20811. */
  20812. if (vctxt->idcNodes == NULL) {
  20813. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20814. xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20815. if (vctxt->idcNodes == NULL) {
  20816. xmlSchemaVErrMemory(vctxt,
  20817. "allocating the IDC node table item list", NULL);
  20818. return (-1);
  20819. }
  20820. vctxt->sizeIdcNodes = 20;
  20821. } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
  20822. vctxt->sizeIdcNodes *= 2;
  20823. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20824. xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
  20825. sizeof(xmlSchemaPSVIIDCNodePtr));
  20826. if (vctxt->idcNodes == NULL) {
  20827. xmlSchemaVErrMemory(vctxt,
  20828. "re-allocating the IDC node table item list", NULL);
  20829. return (-1);
  20830. }
  20831. }
  20832. vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
  20833. return (0);
  20834. }
  20835. /**
  20836. * xmlSchemaIDCStoreKey:
  20837. * @vctxt: the WXS validation context
  20838. * @item: the IDC key
  20839. *
  20840. * The validation context is used to store an IDC key.
  20841. *
  20842. * Returns 0 if succeeded, -1 on internal errors.
  20843. */
  20844. static int
  20845. xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
  20846. xmlSchemaPSVIIDCKeyPtr key)
  20847. {
  20848. /*
  20849. * Add to gobal list.
  20850. */
  20851. if (vctxt->idcKeys == NULL) {
  20852. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20853. xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
  20854. if (vctxt->idcKeys == NULL) {
  20855. xmlSchemaVErrMemory(vctxt,
  20856. "allocating the IDC key storage list", NULL);
  20857. return (-1);
  20858. }
  20859. vctxt->sizeIdcKeys = 40;
  20860. } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
  20861. vctxt->sizeIdcKeys *= 2;
  20862. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20863. xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
  20864. sizeof(xmlSchemaPSVIIDCKeyPtr));
  20865. if (vctxt->idcKeys == NULL) {
  20866. xmlSchemaVErrMemory(vctxt,
  20867. "re-allocating the IDC key storage list", NULL);
  20868. return (-1);
  20869. }
  20870. }
  20871. vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
  20872. return (0);
  20873. }
  20874. /**
  20875. * xmlSchemaIDCAppendNodeTableItem:
  20876. * @bind: the IDC binding
  20877. * @ntItem: the node-table item
  20878. *
  20879. * Appends the IDC node-table item to the binding.
  20880. *
  20881. * Returns 0 on success and -1 on internal errors.
  20882. */
  20883. static int
  20884. xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
  20885. xmlSchemaPSVIIDCNodePtr ntItem)
  20886. {
  20887. if (bind->nodeTable == NULL) {
  20888. bind->sizeNodes = 10;
  20889. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20890. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20891. if (bind->nodeTable == NULL) {
  20892. xmlSchemaVErrMemory(NULL,
  20893. "allocating an array of IDC node-table items", NULL);
  20894. return(-1);
  20895. }
  20896. } else if (bind->sizeNodes <= bind->nbNodes) {
  20897. bind->sizeNodes *= 2;
  20898. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20899. xmlRealloc(bind->nodeTable, bind->sizeNodes *
  20900. sizeof(xmlSchemaPSVIIDCNodePtr));
  20901. if (bind->nodeTable == NULL) {
  20902. xmlSchemaVErrMemory(NULL,
  20903. "re-allocating an array of IDC node-table items", NULL);
  20904. return(-1);
  20905. }
  20906. }
  20907. bind->nodeTable[bind->nbNodes++] = ntItem;
  20908. return(0);
  20909. }
  20910. /**
  20911. * xmlSchemaIDCAcquireBinding:
  20912. * @vctxt: the WXS validation context
  20913. * @matcher: the IDC matcher
  20914. *
  20915. * Looks up an PSVI IDC binding, for the IDC definition and
  20916. * of the given matcher. If none found, a new one is created
  20917. * and added to the IDC table.
  20918. *
  20919. * Returns an IDC binding or NULL on internal errors.
  20920. */
  20921. static xmlSchemaPSVIIDCBindingPtr
  20922. xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
  20923. xmlSchemaIDCMatcherPtr matcher)
  20924. {
  20925. xmlSchemaNodeInfoPtr ielem;
  20926. ielem = vctxt->elemInfos[matcher->depth];
  20927. if (ielem->idcTable == NULL) {
  20928. ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20929. if (ielem->idcTable == NULL)
  20930. return (NULL);
  20931. return(ielem->idcTable);
  20932. } else {
  20933. xmlSchemaPSVIIDCBindingPtr bind = NULL;
  20934. bind = ielem->idcTable;
  20935. do {
  20936. if (bind->definition == matcher->aidc->def)
  20937. return(bind);
  20938. if (bind->next == NULL) {
  20939. bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20940. if (bind->next == NULL)
  20941. return (NULL);
  20942. return(bind->next);
  20943. }
  20944. bind = bind->next;
  20945. } while (bind != NULL);
  20946. }
  20947. return (NULL);
  20948. }
  20949. static xmlSchemaItemListPtr
  20950. xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  20951. xmlSchemaIDCMatcherPtr matcher)
  20952. {
  20953. if (matcher->targets == NULL)
  20954. matcher->targets = xmlSchemaItemListCreate();
  20955. return(matcher->targets);
  20956. }
  20957. /**
  20958. * xmlSchemaIDCFreeKey:
  20959. * @key: the IDC key
  20960. *
  20961. * Frees an IDC key together with its compiled value.
  20962. */
  20963. static void
  20964. xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
  20965. {
  20966. if (key->val != NULL)
  20967. xmlSchemaFreeValue(key->val);
  20968. xmlFree(key);
  20969. }
  20970. /**
  20971. * xmlSchemaIDCFreeBinding:
  20972. *
  20973. * Frees an IDC binding. Note that the node table-items
  20974. * are not freed.
  20975. */
  20976. static void
  20977. xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
  20978. {
  20979. if (bind->nodeTable != NULL)
  20980. xmlFree(bind->nodeTable);
  20981. if (bind->dupls != NULL)
  20982. xmlSchemaItemListFree(bind->dupls);
  20983. xmlFree(bind);
  20984. }
  20985. /**
  20986. * xmlSchemaIDCFreeIDCTable:
  20987. * @bind: the first IDC binding in the list
  20988. *
  20989. * Frees an IDC table, i.e. all the IDC bindings in the list.
  20990. */
  20991. static void
  20992. xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
  20993. {
  20994. xmlSchemaPSVIIDCBindingPtr prev;
  20995. while (bind != NULL) {
  20996. prev = bind;
  20997. bind = bind->next;
  20998. xmlSchemaIDCFreeBinding(prev);
  20999. }
  21000. }
  21001. /**
  21002. * xmlSchemaIDCFreeMatcherList:
  21003. * @matcher: the first IDC matcher in the list
  21004. *
  21005. * Frees a list of IDC matchers.
  21006. */
  21007. static void
  21008. xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
  21009. {
  21010. xmlSchemaIDCMatcherPtr next;
  21011. while (matcher != NULL) {
  21012. next = matcher->next;
  21013. if (matcher->keySeqs != NULL) {
  21014. int i;
  21015. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21016. if (matcher->keySeqs[i] != NULL)
  21017. xmlFree(matcher->keySeqs[i]);
  21018. xmlFree(matcher->keySeqs);
  21019. }
  21020. if (matcher->targets != NULL) {
  21021. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21022. int i;
  21023. xmlSchemaPSVIIDCNodePtr idcNode;
  21024. /*
  21025. * Node-table items for keyrefs are not stored globally
  21026. * to the validation context, since they are not bubbled.
  21027. * We need to free them here.
  21028. */
  21029. for (i = 0; i < matcher->targets->nbItems; i++) {
  21030. idcNode =
  21031. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21032. xmlFree(idcNode->keys);
  21033. xmlFree(idcNode);
  21034. }
  21035. }
  21036. xmlSchemaItemListFree(matcher->targets);
  21037. }
  21038. xmlFree(matcher);
  21039. matcher = next;
  21040. }
  21041. }
  21042. /**
  21043. * xmlSchemaIDCReleaseMatcherList:
  21044. * @vctxt: the WXS validation context
  21045. * @matcher: the first IDC matcher in the list
  21046. *
  21047. * Caches a list of IDC matchers for reuse.
  21048. */
  21049. static void
  21050. xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
  21051. xmlSchemaIDCMatcherPtr matcher)
  21052. {
  21053. xmlSchemaIDCMatcherPtr next;
  21054. while (matcher != NULL) {
  21055. next = matcher->next;
  21056. if (matcher->keySeqs != NULL) {
  21057. int i;
  21058. /*
  21059. * Don't free the array, but only the content.
  21060. */
  21061. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21062. if (matcher->keySeqs[i] != NULL) {
  21063. xmlFree(matcher->keySeqs[i]);
  21064. matcher->keySeqs[i] = NULL;
  21065. }
  21066. }
  21067. if (matcher->targets) {
  21068. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21069. int i;
  21070. xmlSchemaPSVIIDCNodePtr idcNode;
  21071. /*
  21072. * Node-table items for keyrefs are not stored globally
  21073. * to the validation context, since they are not bubbled.
  21074. * We need to free them here.
  21075. */
  21076. for (i = 0; i < matcher->targets->nbItems; i++) {
  21077. idcNode =
  21078. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21079. xmlFree(idcNode->keys);
  21080. xmlFree(idcNode);
  21081. }
  21082. }
  21083. xmlSchemaItemListFree(matcher->targets);
  21084. matcher->targets = NULL;
  21085. }
  21086. matcher->next = NULL;
  21087. /*
  21088. * Cache the matcher.
  21089. */
  21090. if (vctxt->idcMatcherCache != NULL)
  21091. matcher->nextCached = vctxt->idcMatcherCache;
  21092. vctxt->idcMatcherCache = matcher;
  21093. matcher = next;
  21094. }
  21095. }
  21096. /**
  21097. * xmlSchemaIDCAddStateObject:
  21098. * @vctxt: the WXS validation context
  21099. * @matcher: the IDC matcher
  21100. * @sel: the XPath information
  21101. * @parent: the parent "selector" state object if any
  21102. * @type: "selector" or "field"
  21103. *
  21104. * Creates/reuses and activates state objects for the given
  21105. * XPath information; if the XPath expression consists of unions,
  21106. * multiple state objects are created for every unioned expression.
  21107. *
  21108. * Returns 0 on success and -1 on internal errors.
  21109. */
  21110. static int
  21111. xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
  21112. xmlSchemaIDCMatcherPtr matcher,
  21113. xmlSchemaIDCSelectPtr sel,
  21114. int type)
  21115. {
  21116. xmlSchemaIDCStateObjPtr sto;
  21117. /*
  21118. * Reuse the state objects from the pool.
  21119. */
  21120. if (vctxt->xpathStatePool != NULL) {
  21121. sto = vctxt->xpathStatePool;
  21122. vctxt->xpathStatePool = sto->next;
  21123. sto->next = NULL;
  21124. } else {
  21125. /*
  21126. * Create a new state object.
  21127. */
  21128. sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
  21129. if (sto == NULL) {
  21130. xmlSchemaVErrMemory(NULL,
  21131. "allocating an IDC state object", NULL);
  21132. return (-1);
  21133. }
  21134. memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
  21135. }
  21136. /*
  21137. * Add to global list.
  21138. */
  21139. if (vctxt->xpathStates != NULL)
  21140. sto->next = vctxt->xpathStates;
  21141. vctxt->xpathStates = sto;
  21142. /*
  21143. * Free the old xpath validation context.
  21144. */
  21145. if (sto->xpathCtxt != NULL)
  21146. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  21147. /*
  21148. * Create a new XPath (pattern) validation context.
  21149. */
  21150. sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
  21151. (xmlPatternPtr) sel->xpathComp);
  21152. if (sto->xpathCtxt == NULL) {
  21153. VERROR_INT("xmlSchemaIDCAddStateObject",
  21154. "failed to create an XPath validation context");
  21155. return (-1);
  21156. }
  21157. sto->type = type;
  21158. sto->depth = vctxt->depth;
  21159. sto->matcher = matcher;
  21160. sto->sel = sel;
  21161. sto->nbHistory = 0;
  21162. #ifdef DEBUG_IDC
  21163. xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
  21164. sto->sel->xpath);
  21165. #endif
  21166. return (0);
  21167. }
  21168. /**
  21169. * xmlSchemaXPathEvaluate:
  21170. * @vctxt: the WXS validation context
  21171. * @nodeType: the nodeType of the current node
  21172. *
  21173. * Evaluates all active XPath state objects.
  21174. *
  21175. * Returns the number of IC "field" state objects which resolved to
  21176. * this node, 0 if none resolved and -1 on internal errors.
  21177. */
  21178. static int
  21179. xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
  21180. xmlElementType nodeType)
  21181. {
  21182. xmlSchemaIDCStateObjPtr sto, head = NULL, first;
  21183. int res, resolved = 0, depth = vctxt->depth;
  21184. if (vctxt->xpathStates == NULL)
  21185. return (0);
  21186. if (nodeType == XML_ATTRIBUTE_NODE)
  21187. depth++;
  21188. #ifdef DEBUG_IDC
  21189. {
  21190. xmlChar *str = NULL;
  21191. xmlGenericError(xmlGenericErrorContext,
  21192. "IDC: EVAL on %s, depth %d, type %d\n",
  21193. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21194. vctxt->inode->localName), depth, nodeType);
  21195. FREE_AND_NULL(str)
  21196. }
  21197. #endif
  21198. /*
  21199. * Process all active XPath state objects.
  21200. */
  21201. first = vctxt->xpathStates;
  21202. sto = first;
  21203. while (sto != head) {
  21204. #ifdef DEBUG_IDC
  21205. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
  21206. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
  21207. sto->matcher->aidc->def->name, sto->sel->xpath);
  21208. else
  21209. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
  21210. sto->matcher->aidc->def->name, sto->sel->xpath);
  21211. #endif
  21212. if (nodeType == XML_ELEMENT_NODE)
  21213. res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
  21214. vctxt->inode->localName, vctxt->inode->nsName);
  21215. else
  21216. res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
  21217. vctxt->inode->localName, vctxt->inode->nsName);
  21218. if (res == -1) {
  21219. VERROR_INT("xmlSchemaXPathEvaluate",
  21220. "calling xmlStreamPush()");
  21221. return (-1);
  21222. }
  21223. if (res == 0)
  21224. goto next_sto;
  21225. /*
  21226. * Full match.
  21227. */
  21228. #ifdef DEBUG_IDC
  21229. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21230. "MATCH\n");
  21231. #endif
  21232. /*
  21233. * Register a match in the state object history.
  21234. */
  21235. if (sto->history == NULL) {
  21236. sto->history = (int *) xmlMalloc(5 * sizeof(int));
  21237. if (sto->history == NULL) {
  21238. xmlSchemaVErrMemory(NULL,
  21239. "allocating the state object history", NULL);
  21240. return(-1);
  21241. }
  21242. sto->sizeHistory = 5;
  21243. } else if (sto->sizeHistory <= sto->nbHistory) {
  21244. sto->sizeHistory *= 2;
  21245. sto->history = (int *) xmlRealloc(sto->history,
  21246. sto->sizeHistory * sizeof(int));
  21247. if (sto->history == NULL) {
  21248. xmlSchemaVErrMemory(NULL,
  21249. "re-allocating the state object history", NULL);
  21250. return(-1);
  21251. }
  21252. }
  21253. sto->history[sto->nbHistory++] = depth;
  21254. #ifdef DEBUG_IDC
  21255. xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
  21256. vctxt->depth);
  21257. #endif
  21258. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21259. xmlSchemaIDCSelectPtr sel;
  21260. /*
  21261. * Activate state objects for the IDC fields of
  21262. * the IDC selector.
  21263. */
  21264. #ifdef DEBUG_IDC
  21265. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21266. "activating field states\n");
  21267. #endif
  21268. sel = sto->matcher->aidc->def->fields;
  21269. while (sel != NULL) {
  21270. if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
  21271. sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
  21272. return (-1);
  21273. sel = sel->next;
  21274. }
  21275. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21276. /*
  21277. * An IDC key node was found by the IDC field.
  21278. */
  21279. #ifdef DEBUG_IDC
  21280. xmlGenericError(xmlGenericErrorContext,
  21281. "IDC: key found\n");
  21282. #endif
  21283. /*
  21284. * Notify that the character value of this node is
  21285. * needed.
  21286. */
  21287. if (resolved == 0) {
  21288. if ((vctxt->inode->flags &
  21289. XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
  21290. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  21291. }
  21292. resolved++;
  21293. }
  21294. next_sto:
  21295. if (sto->next == NULL) {
  21296. /*
  21297. * Evaluate field state objects created on this node as well.
  21298. */
  21299. head = first;
  21300. sto = vctxt->xpathStates;
  21301. } else
  21302. sto = sto->next;
  21303. }
  21304. return (resolved);
  21305. }
  21306. static const xmlChar *
  21307. xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21308. xmlChar **buf,
  21309. xmlSchemaPSVIIDCKeyPtr *seq,
  21310. int count)
  21311. {
  21312. int i, res;
  21313. xmlChar *value = NULL;
  21314. *buf = xmlStrdup(BAD_CAST "[");
  21315. for (i = 0; i < count; i++) {
  21316. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21317. res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
  21318. xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
  21319. &value);
  21320. if (res == 0)
  21321. *buf = xmlStrcat(*buf, BAD_CAST value);
  21322. else {
  21323. VERROR_INT("xmlSchemaFormatIDCKeySequence",
  21324. "failed to compute a canonical value");
  21325. *buf = xmlStrcat(*buf, BAD_CAST "???");
  21326. }
  21327. if (i < count -1)
  21328. *buf = xmlStrcat(*buf, BAD_CAST "', ");
  21329. else
  21330. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21331. if (value != NULL) {
  21332. xmlFree(value);
  21333. value = NULL;
  21334. }
  21335. }
  21336. *buf = xmlStrcat(*buf, BAD_CAST "]");
  21337. return (BAD_CAST *buf);
  21338. }
  21339. /**
  21340. * xmlSchemaXPathPop:
  21341. * @vctxt: the WXS validation context
  21342. *
  21343. * Pops all XPath states.
  21344. *
  21345. * Returns 0 on success and -1 on internal errors.
  21346. */
  21347. static int
  21348. xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
  21349. {
  21350. xmlSchemaIDCStateObjPtr sto;
  21351. int res;
  21352. if (vctxt->xpathStates == NULL)
  21353. return(0);
  21354. sto = vctxt->xpathStates;
  21355. do {
  21356. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21357. if (res == -1)
  21358. return (-1);
  21359. sto = sto->next;
  21360. } while (sto != NULL);
  21361. return(0);
  21362. }
  21363. /**
  21364. * xmlSchemaXPathProcessHistory:
  21365. * @vctxt: the WXS validation context
  21366. * @type: the simple/complex type of the current node if any at all
  21367. * @val: the precompiled value
  21368. *
  21369. * Processes and pops the history items of the IDC state objects.
  21370. * IDC key-sequences are validated/created on IDC bindings.
  21371. *
  21372. * Returns 0 on success and -1 on internal errors.
  21373. */
  21374. static int
  21375. xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
  21376. int depth)
  21377. {
  21378. xmlSchemaIDCStateObjPtr sto, nextsto;
  21379. int res, matchDepth;
  21380. xmlSchemaPSVIIDCKeyPtr key = NULL;
  21381. xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
  21382. if (vctxt->xpathStates == NULL)
  21383. return (0);
  21384. sto = vctxt->xpathStates;
  21385. #ifdef DEBUG_IDC
  21386. {
  21387. xmlChar *str = NULL;
  21388. xmlGenericError(xmlGenericErrorContext,
  21389. "IDC: BACK on %s, depth %d\n",
  21390. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21391. vctxt->inode->localName), vctxt->depth);
  21392. FREE_AND_NULL(str)
  21393. }
  21394. #endif
  21395. /*
  21396. * Evaluate the state objects.
  21397. */
  21398. while (sto != NULL) {
  21399. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21400. if (res == -1) {
  21401. VERROR_INT("xmlSchemaXPathProcessHistory",
  21402. "calling xmlStreamPop()");
  21403. return (-1);
  21404. }
  21405. #ifdef DEBUG_IDC
  21406. xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
  21407. sto->sel->xpath);
  21408. #endif
  21409. if (sto->nbHistory == 0)
  21410. goto deregister_check;
  21411. matchDepth = sto->history[sto->nbHistory -1];
  21412. /*
  21413. * Only matches at the current depth are of interest.
  21414. */
  21415. if (matchDepth != depth) {
  21416. sto = sto->next;
  21417. continue;
  21418. }
  21419. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21420. /*
  21421. * NOTE: According to
  21422. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
  21423. * ... the simple-content of complex types is also allowed.
  21424. */
  21425. if (WXS_IS_COMPLEX(type)) {
  21426. if (WXS_HAS_SIMPLE_CONTENT(type)) {
  21427. /*
  21428. * Sanity check for complex types with simple content.
  21429. */
  21430. simpleType = type->contentTypeDef;
  21431. if (simpleType == NULL) {
  21432. VERROR_INT("xmlSchemaXPathProcessHistory",
  21433. "field resolves to a CT with simple content "
  21434. "but the CT is missing the ST definition");
  21435. return (-1);
  21436. }
  21437. } else
  21438. simpleType = NULL;
  21439. } else
  21440. simpleType = type;
  21441. if (simpleType == NULL) {
  21442. xmlChar *str = NULL;
  21443. /*
  21444. * Not qualified if the field resolves to a node of non
  21445. * simple type.
  21446. */
  21447. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21448. XML_SCHEMAV_CVC_IDC, NULL,
  21449. WXS_BASIC_CAST sto->matcher->aidc->def,
  21450. "The XPath '%s' of a field of %s does evaluate to a node of "
  21451. "non-simple type",
  21452. sto->sel->xpath,
  21453. xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
  21454. FREE_AND_NULL(str);
  21455. sto->nbHistory--;
  21456. goto deregister_check;
  21457. }
  21458. if ((key == NULL) && (vctxt->inode->val == NULL)) {
  21459. /*
  21460. * Failed to provide the normalized value; maybe
  21461. * the value was invalid.
  21462. */
  21463. VERROR(XML_SCHEMAV_CVC_IDC,
  21464. WXS_BASIC_CAST sto->matcher->aidc->def,
  21465. "Warning: No precomputed value available, the value "
  21466. "was either invalid or something strange happend");
  21467. sto->nbHistory--;
  21468. goto deregister_check;
  21469. } else {
  21470. xmlSchemaIDCMatcherPtr matcher = sto->matcher;
  21471. xmlSchemaPSVIIDCKeyPtr *keySeq;
  21472. int pos, idx;
  21473. /*
  21474. * The key will be anchored on the matcher's list of
  21475. * key-sequences. The position in this list is determined
  21476. * by the target node's depth relative to the matcher's
  21477. * depth of creation (i.e. the depth of the scope element).
  21478. *
  21479. * Element Depth Pos List-entries
  21480. * <scope> 0 NULL
  21481. * <bar> 1 NULL
  21482. * <target/> 2 2 target
  21483. * <bar>
  21484. * </scope>
  21485. *
  21486. * The size of the list is only dependant on the depth of
  21487. * the tree.
  21488. * An entry will be NULLed in selector_leave, i.e. when
  21489. * we hit the target's
  21490. */
  21491. pos = sto->depth - matcher->depth;
  21492. idx = sto->sel->index;
  21493. /*
  21494. * Create/grow the array of key-sequences.
  21495. */
  21496. if (matcher->keySeqs == NULL) {
  21497. if (pos > 9)
  21498. matcher->sizeKeySeqs = pos * 2;
  21499. else
  21500. matcher->sizeKeySeqs = 10;
  21501. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21502. xmlMalloc(matcher->sizeKeySeqs *
  21503. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21504. if (matcher->keySeqs == NULL) {
  21505. xmlSchemaVErrMemory(NULL,
  21506. "allocating an array of key-sequences",
  21507. NULL);
  21508. return(-1);
  21509. }
  21510. memset(matcher->keySeqs, 0,
  21511. matcher->sizeKeySeqs *
  21512. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21513. } else if (pos >= matcher->sizeKeySeqs) {
  21514. int i = matcher->sizeKeySeqs;
  21515. matcher->sizeKeySeqs *= 2;
  21516. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21517. xmlRealloc(matcher->keySeqs,
  21518. matcher->sizeKeySeqs *
  21519. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21520. if (matcher->keySeqs == NULL) {
  21521. xmlSchemaVErrMemory(NULL,
  21522. "reallocating an array of key-sequences",
  21523. NULL);
  21524. return (-1);
  21525. }
  21526. /*
  21527. * The array needs to be NULLed.
  21528. * TODO: Use memset?
  21529. */
  21530. for (; i < matcher->sizeKeySeqs; i++)
  21531. matcher->keySeqs[i] = NULL;
  21532. }
  21533. /*
  21534. * Get/create the key-sequence.
  21535. */
  21536. keySeq = matcher->keySeqs[pos];
  21537. if (keySeq == NULL) {
  21538. goto create_sequence;
  21539. } else if (keySeq[idx] != NULL) {
  21540. xmlChar *str = NULL;
  21541. /*
  21542. * cvc-identity-constraint:
  21543. * 3 For each node in the �target node set� all
  21544. * of the {fields}, with that node as the context
  21545. * node, evaluate to either an empty node-set or
  21546. * a node-set with exactly one member, which must
  21547. * have a simple type.
  21548. *
  21549. * The key was already set; report an error.
  21550. */
  21551. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21552. XML_SCHEMAV_CVC_IDC, NULL,
  21553. WXS_BASIC_CAST matcher->aidc->def,
  21554. "The XPath '%s' of a field of %s evaluates to a "
  21555. "node-set with more than one member",
  21556. sto->sel->xpath,
  21557. xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
  21558. FREE_AND_NULL(str);
  21559. sto->nbHistory--;
  21560. goto deregister_check;
  21561. } else
  21562. goto create_key;
  21563. create_sequence:
  21564. /*
  21565. * Create a key-sequence.
  21566. */
  21567. keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
  21568. matcher->aidc->def->nbFields *
  21569. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21570. if (keySeq == NULL) {
  21571. xmlSchemaVErrMemory(NULL,
  21572. "allocating an IDC key-sequence", NULL);
  21573. return(-1);
  21574. }
  21575. memset(keySeq, 0, matcher->aidc->def->nbFields *
  21576. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21577. matcher->keySeqs[pos] = keySeq;
  21578. create_key:
  21579. /*
  21580. * Create a key once per node only.
  21581. */
  21582. if (key == NULL) {
  21583. key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
  21584. sizeof(xmlSchemaPSVIIDCKey));
  21585. if (key == NULL) {
  21586. xmlSchemaVErrMemory(NULL,
  21587. "allocating a IDC key", NULL);
  21588. xmlFree(keySeq);
  21589. matcher->keySeqs[pos] = NULL;
  21590. return(-1);
  21591. }
  21592. /*
  21593. * Consume the compiled value.
  21594. */
  21595. key->type = simpleType;
  21596. key->val = vctxt->inode->val;
  21597. vctxt->inode->val = NULL;
  21598. /*
  21599. * Store the key in a global list.
  21600. */
  21601. if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
  21602. xmlSchemaIDCFreeKey(key);
  21603. return (-1);
  21604. }
  21605. }
  21606. keySeq[idx] = key;
  21607. }
  21608. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21609. xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
  21610. /* xmlSchemaPSVIIDCBindingPtr bind; */
  21611. xmlSchemaPSVIIDCNodePtr ntItem;
  21612. xmlSchemaIDCMatcherPtr matcher;
  21613. xmlSchemaIDCPtr idc;
  21614. xmlSchemaItemListPtr targets;
  21615. int pos, i, j, nbKeys;
  21616. /*
  21617. * Here we have the following scenario:
  21618. * An IDC 'selector' state object resolved to a target node,
  21619. * during the time this target node was in the
  21620. * ancestor-or-self axis, the 'field' state object(s) looked
  21621. * out for matching nodes to create a key-sequence for this
  21622. * target node. Now we are back to this target node and need
  21623. * to put the key-sequence, together with the target node
  21624. * itself, into the node-table of the corresponding IDC
  21625. * binding.
  21626. */
  21627. matcher = sto->matcher;
  21628. idc = matcher->aidc->def;
  21629. nbKeys = idc->nbFields;
  21630. pos = depth - matcher->depth;
  21631. /*
  21632. * Check if the matcher has any key-sequences at all, plus
  21633. * if it has a key-sequence for the current target node.
  21634. */
  21635. if ((matcher->keySeqs == NULL) ||
  21636. (matcher->sizeKeySeqs <= pos)) {
  21637. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21638. goto selector_key_error;
  21639. else
  21640. goto selector_leave;
  21641. }
  21642. keySeq = &(matcher->keySeqs[pos]);
  21643. if (*keySeq == NULL) {
  21644. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21645. goto selector_key_error;
  21646. else
  21647. goto selector_leave;
  21648. }
  21649. for (i = 0; i < nbKeys; i++) {
  21650. if ((*keySeq)[i] == NULL) {
  21651. /*
  21652. * Not qualified, if not all fields did resolve.
  21653. */
  21654. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
  21655. /*
  21656. * All fields of a "key" IDC must resolve.
  21657. */
  21658. goto selector_key_error;
  21659. }
  21660. goto selector_leave;
  21661. }
  21662. }
  21663. /*
  21664. * All fields did resolve.
  21665. */
  21666. /*
  21667. * 4.1 If the {identity-constraint category} is unique(/key),
  21668. * then no two members of the �qualified node set� have
  21669. * �key-sequences� whose members are pairwise equal, as
  21670. * defined by Equal in [XML Schemas: Datatypes].
  21671. *
  21672. * Get the IDC binding from the matcher and check for
  21673. * duplicate key-sequences.
  21674. */
  21675. #if 0
  21676. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21677. #endif
  21678. targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
  21679. if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
  21680. (targets->nbItems != 0)) {
  21681. xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
  21682. i = 0;
  21683. res = 0;
  21684. /*
  21685. * Compare the key-sequences, key by key.
  21686. */
  21687. do {
  21688. bkeySeq =
  21689. ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
  21690. for (j = 0; j < nbKeys; j++) {
  21691. ckey = (*keySeq)[j];
  21692. bkey = bkeySeq[j];
  21693. res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
  21694. if (res == -1) {
  21695. return (-1);
  21696. } else if (res == 0) {
  21697. /*
  21698. * One of the keys differs, so the key-sequence
  21699. * won't be equal; get out.
  21700. */
  21701. break;
  21702. }
  21703. }
  21704. if (res == 1) {
  21705. /*
  21706. * Duplicate key-sequence found.
  21707. */
  21708. break;
  21709. }
  21710. i++;
  21711. } while (i < targets->nbItems);
  21712. if (i != targets->nbItems) {
  21713. xmlChar *str = NULL, *strB = NULL;
  21714. /*
  21715. * TODO: Try to report the key-sequence.
  21716. */
  21717. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21718. XML_SCHEMAV_CVC_IDC, NULL,
  21719. WXS_BASIC_CAST idc,
  21720. "Duplicate key-sequence %s in %s",
  21721. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  21722. (*keySeq), nbKeys),
  21723. xmlSchemaGetIDCDesignation(&strB, idc));
  21724. FREE_AND_NULL(str);
  21725. FREE_AND_NULL(strB);
  21726. goto selector_leave;
  21727. }
  21728. }
  21729. /*
  21730. * Add a node-table item to the IDC binding.
  21731. */
  21732. ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
  21733. sizeof(xmlSchemaPSVIIDCNode));
  21734. if (ntItem == NULL) {
  21735. xmlSchemaVErrMemory(NULL,
  21736. "allocating an IDC node-table item", NULL);
  21737. xmlFree(*keySeq);
  21738. *keySeq = NULL;
  21739. return(-1);
  21740. }
  21741. memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
  21742. /*
  21743. * Store the node-table item in a global list.
  21744. */
  21745. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21746. if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
  21747. xmlFree(ntItem);
  21748. xmlFree(*keySeq);
  21749. *keySeq = NULL;
  21750. return (-1);
  21751. }
  21752. ntItem->nodeQNameID = -1;
  21753. } else {
  21754. /*
  21755. * Save a cached QName for this node on the IDC node, to be
  21756. * able to report it, even if the node is not saved.
  21757. */
  21758. ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
  21759. vctxt->inode->localName, vctxt->inode->nsName);
  21760. if (ntItem->nodeQNameID == -1) {
  21761. xmlFree(ntItem);
  21762. xmlFree(*keySeq);
  21763. *keySeq = NULL;
  21764. return (-1);
  21765. }
  21766. }
  21767. /*
  21768. * Init the node-table item: Save the node, position and
  21769. * consume the key-sequence.
  21770. */
  21771. ntItem->node = vctxt->node;
  21772. ntItem->nodeLine = vctxt->inode->nodeLine;
  21773. ntItem->keys = *keySeq;
  21774. *keySeq = NULL;
  21775. #if 0
  21776. if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
  21777. #endif
  21778. if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
  21779. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21780. /*
  21781. * Free the item, since keyref items won't be
  21782. * put on a global list.
  21783. */
  21784. xmlFree(ntItem->keys);
  21785. xmlFree(ntItem);
  21786. }
  21787. return (-1);
  21788. }
  21789. goto selector_leave;
  21790. selector_key_error:
  21791. {
  21792. xmlChar *str = NULL;
  21793. /*
  21794. * 4.2.1 (KEY) The �target node set� and the
  21795. * �qualified node set� are equal, that is, every
  21796. * member of the �target node set� is also a member
  21797. * of the �qualified node set� and vice versa.
  21798. */
  21799. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21800. XML_SCHEMAV_CVC_IDC, NULL,
  21801. WXS_BASIC_CAST idc,
  21802. "Not all fields of %s evaluate to a node",
  21803. xmlSchemaGetIDCDesignation(&str, idc), NULL);
  21804. FREE_AND_NULL(str);
  21805. }
  21806. selector_leave:
  21807. /*
  21808. * Free the key-sequence if not added to the IDC table.
  21809. */
  21810. if ((keySeq != NULL) && (*keySeq != NULL)) {
  21811. xmlFree(*keySeq);
  21812. *keySeq = NULL;
  21813. }
  21814. } /* if selector */
  21815. sto->nbHistory--;
  21816. deregister_check:
  21817. /*
  21818. * Deregister state objects if they reach the depth of creation.
  21819. */
  21820. if ((sto->nbHistory == 0) && (sto->depth == depth)) {
  21821. #ifdef DEBUG_IDC
  21822. xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
  21823. sto->sel->xpath);
  21824. #endif
  21825. if (vctxt->xpathStates != sto) {
  21826. VERROR_INT("xmlSchemaXPathProcessHistory",
  21827. "The state object to be removed is not the first "
  21828. "in the list");
  21829. }
  21830. nextsto = sto->next;
  21831. /*
  21832. * Unlink from the list of active XPath state objects.
  21833. */
  21834. vctxt->xpathStates = sto->next;
  21835. sto->next = vctxt->xpathStatePool;
  21836. /*
  21837. * Link it to the pool of reusable state objects.
  21838. */
  21839. vctxt->xpathStatePool = sto;
  21840. sto = nextsto;
  21841. } else
  21842. sto = sto->next;
  21843. } /* while (sto != NULL) */
  21844. return (0);
  21845. }
  21846. /**
  21847. * xmlSchemaIDCRegisterMatchers:
  21848. * @vctxt: the WXS validation context
  21849. * @elemDecl: the element declaration
  21850. *
  21851. * Creates helper objects to evaluate IDC selectors/fields
  21852. * successively.
  21853. *
  21854. * Returns 0 if OK and -1 on internal errors.
  21855. */
  21856. static int
  21857. xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
  21858. xmlSchemaElementPtr elemDecl)
  21859. {
  21860. xmlSchemaIDCMatcherPtr matcher, last = NULL;
  21861. xmlSchemaIDCPtr idc, refIdc;
  21862. xmlSchemaIDCAugPtr aidc;
  21863. idc = (xmlSchemaIDCPtr) elemDecl->idcs;
  21864. if (idc == NULL)
  21865. return (0);
  21866. #ifdef DEBUG_IDC
  21867. {
  21868. xmlChar *str = NULL;
  21869. xmlGenericError(xmlGenericErrorContext,
  21870. "IDC: REGISTER on %s, depth %d\n",
  21871. (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21872. vctxt->inode->localName), vctxt->depth);
  21873. FREE_AND_NULL(str)
  21874. }
  21875. #endif
  21876. if (vctxt->inode->idcMatchers != NULL) {
  21877. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21878. "The chain of IDC matchers is expected to be empty");
  21879. return (-1);
  21880. }
  21881. do {
  21882. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21883. /*
  21884. * Since IDCs bubbles are expensive we need to know the
  21885. * depth at which the bubbles should stop; this will be
  21886. * the depth of the top-most keyref IDC. If no keyref
  21887. * references a key/unique IDC, the keyrefDepth will
  21888. * be -1, indicating that no bubbles are needed.
  21889. */
  21890. refIdc = (xmlSchemaIDCPtr) idc->ref->item;
  21891. if (refIdc != NULL) {
  21892. /*
  21893. * Remember that we have keyrefs on this node.
  21894. */
  21895. vctxt->inode->hasKeyrefs = 1;
  21896. /*
  21897. * Lookup the referenced augmented IDC info.
  21898. */
  21899. aidc = vctxt->aidcs;
  21900. while (aidc != NULL) {
  21901. if (aidc->def == refIdc)
  21902. break;
  21903. aidc = aidc->next;
  21904. }
  21905. if (aidc == NULL) {
  21906. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21907. "Could not find an augmented IDC item for an IDC "
  21908. "definition");
  21909. return (-1);
  21910. }
  21911. if ((aidc->keyrefDepth == -1) ||
  21912. (vctxt->depth < aidc->keyrefDepth))
  21913. aidc->keyrefDepth = vctxt->depth;
  21914. }
  21915. }
  21916. /*
  21917. * Lookup the augmented IDC item for the IDC definition.
  21918. */
  21919. aidc = vctxt->aidcs;
  21920. while (aidc != NULL) {
  21921. if (aidc->def == idc)
  21922. break;
  21923. aidc = aidc->next;
  21924. }
  21925. if (aidc == NULL) {
  21926. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21927. "Could not find an augmented IDC item for an IDC definition");
  21928. return (-1);
  21929. }
  21930. /*
  21931. * Create an IDC matcher for every IDC definition.
  21932. */
  21933. if (vctxt->idcMatcherCache != NULL) {
  21934. /*
  21935. * Reuse a cached matcher.
  21936. */
  21937. matcher = vctxt->idcMatcherCache;
  21938. vctxt->idcMatcherCache = matcher->nextCached;
  21939. matcher->nextCached = NULL;
  21940. } else {
  21941. matcher = (xmlSchemaIDCMatcherPtr)
  21942. xmlMalloc(sizeof(xmlSchemaIDCMatcher));
  21943. if (matcher == NULL) {
  21944. xmlSchemaVErrMemory(vctxt,
  21945. "allocating an IDC matcher", NULL);
  21946. return (-1);
  21947. }
  21948. memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
  21949. }
  21950. if (last == NULL)
  21951. vctxt->inode->idcMatchers = matcher;
  21952. else
  21953. last->next = matcher;
  21954. last = matcher;
  21955. matcher->type = IDC_MATCHER;
  21956. matcher->depth = vctxt->depth;
  21957. matcher->aidc = aidc;
  21958. matcher->idcType = aidc->def->type;
  21959. #ifdef DEBUG_IDC
  21960. xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
  21961. #endif
  21962. /*
  21963. * Init the automaton state object.
  21964. */
  21965. if (xmlSchemaIDCAddStateObject(vctxt, matcher,
  21966. idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
  21967. return (-1);
  21968. idc = idc->next;
  21969. } while (idc != NULL);
  21970. return (0);
  21971. }
  21972. static int
  21973. xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
  21974. xmlSchemaNodeInfoPtr ielem)
  21975. {
  21976. xmlSchemaPSVIIDCBindingPtr bind;
  21977. int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
  21978. xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
  21979. xmlSchemaPSVIIDCNodePtr *targets, *dupls;
  21980. xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
  21981. /* vctxt->createIDCNodeTables */
  21982. while (matcher != NULL) {
  21983. /*
  21984. * Skip keyref IDCs and empty IDC target-lists.
  21985. */
  21986. if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
  21987. WXS_ILIST_IS_EMPTY(matcher->targets))
  21988. {
  21989. matcher = matcher->next;
  21990. continue;
  21991. }
  21992. /*
  21993. * If we _want_ the IDC node-table to be created in any case
  21994. * then do so. Otherwise create them only if keyrefs need them.
  21995. */
  21996. if ((! vctxt->createIDCNodeTables) &&
  21997. ((matcher->aidc->keyrefDepth == -1) ||
  21998. (matcher->aidc->keyrefDepth > vctxt->depth)))
  21999. {
  22000. matcher = matcher->next;
  22001. continue;
  22002. }
  22003. /*
  22004. * Get/create the IDC binding on this element for the IDC definition.
  22005. */
  22006. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  22007. if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
  22008. dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
  22009. nbDupls = bind->dupls->nbItems;
  22010. } else {
  22011. dupls = NULL;
  22012. nbDupls = 0;
  22013. }
  22014. if (bind->nodeTable != NULL) {
  22015. nbNodeTable = bind->nbNodes;
  22016. } else {
  22017. nbNodeTable = 0;
  22018. }
  22019. if ((nbNodeTable == 0) && (nbDupls == 0)) {
  22020. /*
  22021. * Transfer all IDC target-nodes to the IDC node-table.
  22022. */
  22023. bind->nodeTable =
  22024. (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22025. bind->sizeNodes = matcher->targets->sizeItems;
  22026. bind->nbNodes = matcher->targets->nbItems;
  22027. matcher->targets->items = NULL;
  22028. matcher->targets->sizeItems = 0;
  22029. matcher->targets->nbItems = 0;
  22030. } else {
  22031. /*
  22032. * Compare the key-sequences and add to the IDC node-table.
  22033. */
  22034. nbTargets = matcher->targets->nbItems;
  22035. targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22036. nbFields = matcher->aidc->def->nbFields;
  22037. i = 0;
  22038. do {
  22039. keys = targets[i]->keys;
  22040. if (nbDupls) {
  22041. /*
  22042. * Search in already found duplicates first.
  22043. */
  22044. j = 0;
  22045. do {
  22046. if (nbFields == 1) {
  22047. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22048. dupls[j]->keys[0]->val);
  22049. if (res == -1)
  22050. goto internal_error;
  22051. if (res == 1) {
  22052. /*
  22053. * Equal key-sequence.
  22054. */
  22055. goto next_target;
  22056. }
  22057. } else {
  22058. res = 0;
  22059. ntkeys = dupls[j]->keys;
  22060. for (k = 0; k < nbFields; k++) {
  22061. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22062. ntkeys[k]->val);
  22063. if (res == -1)
  22064. goto internal_error;
  22065. if (res == 0) {
  22066. /*
  22067. * One of the keys differs.
  22068. */
  22069. break;
  22070. }
  22071. }
  22072. if (res == 1) {
  22073. /*
  22074. * Equal key-sequence found.
  22075. */
  22076. goto next_target;
  22077. }
  22078. }
  22079. j++;
  22080. } while (j < nbDupls);
  22081. }
  22082. if (nbNodeTable) {
  22083. j = 0;
  22084. do {
  22085. if (nbFields == 1) {
  22086. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22087. bind->nodeTable[j]->keys[0]->val);
  22088. if (res == -1)
  22089. goto internal_error;
  22090. if (res == 0) {
  22091. /*
  22092. * The key-sequence differs.
  22093. */
  22094. goto next_node_table_entry;
  22095. }
  22096. } else {
  22097. res = 0;
  22098. ntkeys = bind->nodeTable[j]->keys;
  22099. for (k = 0; k < nbFields; k++) {
  22100. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22101. ntkeys[k]->val);
  22102. if (res == -1)
  22103. goto internal_error;
  22104. if (res == 0) {
  22105. /*
  22106. * One of the keys differs.
  22107. */
  22108. goto next_node_table_entry;
  22109. }
  22110. }
  22111. }
  22112. /*
  22113. * Add the duplicate to the list of duplicates.
  22114. */
  22115. if (bind->dupls == NULL) {
  22116. bind->dupls = xmlSchemaItemListCreate();
  22117. if (bind->dupls == NULL)
  22118. goto internal_error;
  22119. }
  22120. if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
  22121. goto internal_error;
  22122. /*
  22123. * Remove the duplicate entry from the IDC node-table.
  22124. */
  22125. bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
  22126. bind->nbNodes--;
  22127. goto next_target;
  22128. next_node_table_entry:
  22129. j++;
  22130. } while (j < nbNodeTable);
  22131. }
  22132. /*
  22133. * If everything is fine, then add the IDC target-node to
  22134. * the IDC node-table.
  22135. */
  22136. if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
  22137. goto internal_error;
  22138. next_target:
  22139. i++;
  22140. } while (i < nbTargets);
  22141. }
  22142. matcher = matcher->next;
  22143. }
  22144. return(0);
  22145. internal_error:
  22146. return(-1);
  22147. }
  22148. /**
  22149. * xmlSchemaBubbleIDCNodeTables:
  22150. * @depth: the current tree depth
  22151. *
  22152. * Merges IDC bindings of an element at @depth into the corresponding IDC
  22153. * bindings of its parent element. If a duplicate note-table entry is found,
  22154. * both, the parent node-table entry and child entry are discarded from the
  22155. * node-table of the parent.
  22156. *
  22157. * Returns 0 if OK and -1 on internal errors.
  22158. */
  22159. static int
  22160. xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
  22161. {
  22162. xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
  22163. xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
  22164. xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
  22165. xmlSchemaIDCAugPtr aidc;
  22166. int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
  22167. bind = vctxt->inode->idcTable;
  22168. if (bind == NULL) {
  22169. /* Fine, no table, no bubbles. */
  22170. return (0);
  22171. }
  22172. parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
  22173. /*
  22174. * Walk all bindings; create new or add to existing bindings.
  22175. * Remove duplicate key-sequences.
  22176. */
  22177. while (bind != NULL) {
  22178. if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
  22179. goto next_binding;
  22180. /*
  22181. * Check if the key/unique IDC table needs to be bubbled.
  22182. */
  22183. if (! vctxt->createIDCNodeTables) {
  22184. aidc = vctxt->aidcs;
  22185. do {
  22186. if (aidc->def == bind->definition) {
  22187. if ((aidc->keyrefDepth == -1) ||
  22188. (aidc->keyrefDepth >= vctxt->depth)) {
  22189. goto next_binding;
  22190. }
  22191. break;
  22192. }
  22193. aidc = aidc->next;
  22194. } while (aidc != NULL);
  22195. }
  22196. if (parTable != NULL)
  22197. parBind = *parTable;
  22198. /*
  22199. * Search a matching parent binding for the
  22200. * IDC definition.
  22201. */
  22202. while (parBind != NULL) {
  22203. if (parBind->definition == bind->definition)
  22204. break;
  22205. parBind = parBind->next;
  22206. }
  22207. if (parBind != NULL) {
  22208. /*
  22209. * Compare every node-table entry of the child node,
  22210. * i.e. the key-sequence within, ...
  22211. */
  22212. oldNum = parBind->nbNodes; /* Skip newly added items. */
  22213. if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
  22214. oldDupls = parBind->dupls->nbItems;
  22215. dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
  22216. } else {
  22217. dupls = NULL;
  22218. oldDupls = 0;
  22219. }
  22220. parNodes = parBind->nodeTable;
  22221. nbFields = bind->definition->nbFields;
  22222. for (i = 0; i < bind->nbNodes; i++) {
  22223. node = bind->nodeTable[i];
  22224. if (node == NULL)
  22225. continue;
  22226. /*
  22227. * ...with every key-sequence of the parent node, already
  22228. * evaluated to be a duplicate key-sequence.
  22229. */
  22230. if (oldDupls) {
  22231. j = 0;
  22232. while (j < oldDupls) {
  22233. if (nbFields == 1) {
  22234. ret = xmlSchemaAreValuesEqual(
  22235. node->keys[0]->val,
  22236. dupls[j]->keys[0]->val);
  22237. if (ret == -1)
  22238. goto internal_error;
  22239. if (ret == 0) {
  22240. j++;
  22241. continue;
  22242. }
  22243. } else {
  22244. parNode = dupls[j];
  22245. for (k = 0; k < nbFields; k++) {
  22246. ret = xmlSchemaAreValuesEqual(
  22247. node->keys[k]->val,
  22248. parNode->keys[k]->val);
  22249. if (ret == -1)
  22250. goto internal_error;
  22251. if (ret == 0)
  22252. break;
  22253. }
  22254. }
  22255. if (ret == 1)
  22256. /* Duplicate found. */
  22257. break;
  22258. j++;
  22259. }
  22260. if (j != oldDupls) {
  22261. /* Duplicate found. Skip this entry. */
  22262. continue;
  22263. }
  22264. }
  22265. /*
  22266. * ... and with every key-sequence of the parent node.
  22267. */
  22268. if (oldNum) {
  22269. j = 0;
  22270. while (j < oldNum) {
  22271. parNode = parNodes[j];
  22272. if (nbFields == 1) {
  22273. ret = xmlSchemaAreValuesEqual(
  22274. node->keys[0]->val,
  22275. parNode->keys[0]->val);
  22276. if (ret == -1)
  22277. goto internal_error;
  22278. if (ret == 0) {
  22279. j++;
  22280. continue;
  22281. }
  22282. } else {
  22283. for (k = 0; k < nbFields; k++) {
  22284. ret = xmlSchemaAreValuesEqual(
  22285. node->keys[k]->val,
  22286. parNode->keys[k]->val);
  22287. if (ret == -1)
  22288. goto internal_error;
  22289. if (ret == 0)
  22290. break;
  22291. }
  22292. }
  22293. if (ret == 1)
  22294. /* Duplicate found. */
  22295. break;
  22296. j++;
  22297. }
  22298. if (j != oldNum) {
  22299. /*
  22300. * Handle duplicates. Move the duplicate in
  22301. * the parent's node-table to the list of
  22302. * duplicates.
  22303. */
  22304. oldNum--;
  22305. parBind->nbNodes--;
  22306. /*
  22307. * Move last old item to pos of duplicate.
  22308. */
  22309. parNodes[j] = parNodes[oldNum];
  22310. if (parBind->nbNodes != oldNum) {
  22311. /*
  22312. * If new items exist, move last new item to
  22313. * last of old items.
  22314. */
  22315. parNodes[oldNum] =
  22316. parNodes[parBind->nbNodes];
  22317. }
  22318. if (parBind->dupls == NULL) {
  22319. parBind->dupls = xmlSchemaItemListCreate();
  22320. if (parBind->dupls == NULL)
  22321. goto internal_error;
  22322. }
  22323. xmlSchemaItemListAdd(parBind->dupls, parNode);
  22324. } else {
  22325. /*
  22326. * Add the node-table entry (node and key-sequence) of
  22327. * the child node to the node table of the parent node.
  22328. */
  22329. if (parBind->nodeTable == NULL) {
  22330. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22331. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  22332. if (parBind->nodeTable == NULL) {
  22333. xmlSchemaVErrMemory(NULL,
  22334. "allocating IDC list of node-table items", NULL);
  22335. goto internal_error;
  22336. }
  22337. parBind->sizeNodes = 1;
  22338. } else if (parBind->nbNodes >= parBind->sizeNodes) {
  22339. parBind->sizeNodes *= 2;
  22340. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22341. xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
  22342. sizeof(xmlSchemaPSVIIDCNodePtr));
  22343. if (parBind->nodeTable == NULL) {
  22344. xmlSchemaVErrMemory(NULL,
  22345. "re-allocating IDC list of node-table items", NULL);
  22346. goto internal_error;
  22347. }
  22348. }
  22349. parNodes = parBind->nodeTable;
  22350. /*
  22351. * Append the new node-table entry to the 'new node-table
  22352. * entries' section.
  22353. */
  22354. parNodes[parBind->nbNodes++] = node;
  22355. }
  22356. }
  22357. }
  22358. } else {
  22359. /*
  22360. * No binding for the IDC was found: create a new one and
  22361. * copy all node-tables.
  22362. */
  22363. parBind = xmlSchemaIDCNewBinding(bind->definition);
  22364. if (parBind == NULL)
  22365. goto internal_error;
  22366. /*
  22367. * TODO: Hmm, how to optimize the initial number of
  22368. * allocated entries?
  22369. */
  22370. if (bind->nbNodes != 0) {
  22371. /*
  22372. * Add all IDC node-table entries.
  22373. */
  22374. if (! vctxt->psviExposeIDCNodeTables) {
  22375. /*
  22376. * Just move the entries.
  22377. * NOTE: this is quite save here, since
  22378. * all the keyref lookups have already been
  22379. * performed.
  22380. */
  22381. parBind->nodeTable = bind->nodeTable;
  22382. bind->nodeTable = NULL;
  22383. parBind->sizeNodes = bind->sizeNodes;
  22384. bind->sizeNodes = 0;
  22385. parBind->nbNodes = bind->nbNodes;
  22386. bind->nbNodes = 0;
  22387. } else {
  22388. /*
  22389. * Copy the entries.
  22390. */
  22391. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22392. xmlMalloc(bind->nbNodes *
  22393. sizeof(xmlSchemaPSVIIDCNodePtr));
  22394. if (parBind->nodeTable == NULL) {
  22395. xmlSchemaVErrMemory(NULL,
  22396. "allocating an array of IDC node-table "
  22397. "items", NULL);
  22398. xmlSchemaIDCFreeBinding(parBind);
  22399. goto internal_error;
  22400. }
  22401. parBind->sizeNodes = bind->nbNodes;
  22402. parBind->nbNodes = bind->nbNodes;
  22403. memcpy(parBind->nodeTable, bind->nodeTable,
  22404. bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
  22405. }
  22406. }
  22407. if (bind->dupls) {
  22408. /*
  22409. * Move the duplicates.
  22410. */
  22411. if (parBind->dupls != NULL)
  22412. xmlSchemaItemListFree(parBind->dupls);
  22413. parBind->dupls = bind->dupls;
  22414. bind->dupls = NULL;
  22415. }
  22416. if (parTable != NULL) {
  22417. if (*parTable == NULL)
  22418. *parTable = parBind;
  22419. else {
  22420. parBind->next = *parTable;
  22421. *parTable = parBind;
  22422. }
  22423. }
  22424. }
  22425. next_binding:
  22426. bind = bind->next;
  22427. }
  22428. return (0);
  22429. internal_error:
  22430. return(-1);
  22431. }
  22432. /**
  22433. * xmlSchemaCheckCVCIDCKeyRef:
  22434. * @vctxt: the WXS validation context
  22435. * @elemDecl: the element declaration
  22436. *
  22437. * Check the cvc-idc-keyref constraints.
  22438. */
  22439. static int
  22440. xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
  22441. {
  22442. xmlSchemaIDCMatcherPtr matcher;
  22443. xmlSchemaPSVIIDCBindingPtr bind;
  22444. matcher = vctxt->inode->idcMatchers;
  22445. /*
  22446. * Find a keyref.
  22447. */
  22448. while (matcher != NULL) {
  22449. if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
  22450. matcher->targets &&
  22451. matcher->targets->nbItems)
  22452. {
  22453. int i, j, k, res, nbFields, hasDupls;
  22454. xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
  22455. xmlSchemaPSVIIDCNodePtr refNode = NULL;
  22456. nbFields = matcher->aidc->def->nbFields;
  22457. /*
  22458. * Find the IDC node-table for the referenced IDC key/unique.
  22459. */
  22460. bind = vctxt->inode->idcTable;
  22461. while (bind != NULL) {
  22462. if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
  22463. bind->definition)
  22464. break;
  22465. bind = bind->next;
  22466. }
  22467. hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
  22468. /*
  22469. * Search for a matching key-sequences.
  22470. */
  22471. for (i = 0; i < matcher->targets->nbItems; i++) {
  22472. res = 0;
  22473. refNode = matcher->targets->items[i];
  22474. if (bind != NULL) {
  22475. refKeys = refNode->keys;
  22476. for (j = 0; j < bind->nbNodes; j++) {
  22477. keys = bind->nodeTable[j]->keys;
  22478. for (k = 0; k < nbFields; k++) {
  22479. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22480. refKeys[k]->val);
  22481. if (res == 0)
  22482. break;
  22483. else if (res == -1) {
  22484. return (-1);
  22485. }
  22486. }
  22487. if (res == 1) {
  22488. /*
  22489. * Match found.
  22490. */
  22491. break;
  22492. }
  22493. }
  22494. if ((res == 0) && hasDupls) {
  22495. /*
  22496. * Search in duplicates
  22497. */
  22498. for (j = 0; j < bind->dupls->nbItems; j++) {
  22499. keys = ((xmlSchemaPSVIIDCNodePtr)
  22500. bind->dupls->items[j])->keys;
  22501. for (k = 0; k < nbFields; k++) {
  22502. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22503. refKeys[k]->val);
  22504. if (res == 0)
  22505. break;
  22506. else if (res == -1) {
  22507. return (-1);
  22508. }
  22509. }
  22510. if (res == 1) {
  22511. /*
  22512. * Match in duplicates found.
  22513. */
  22514. xmlChar *str = NULL, *strB = NULL;
  22515. xmlSchemaKeyrefErr(vctxt,
  22516. XML_SCHEMAV_CVC_IDC, refNode,
  22517. (xmlSchemaTypePtr) matcher->aidc->def,
  22518. "More than one match found for "
  22519. "key-sequence %s of keyref '%s'",
  22520. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22521. refNode->keys, nbFields),
  22522. xmlSchemaGetComponentQName(&strB,
  22523. matcher->aidc->def));
  22524. FREE_AND_NULL(str);
  22525. FREE_AND_NULL(strB);
  22526. break;
  22527. }
  22528. }
  22529. }
  22530. }
  22531. if (res == 0) {
  22532. xmlChar *str = NULL, *strB = NULL;
  22533. xmlSchemaKeyrefErr(vctxt,
  22534. XML_SCHEMAV_CVC_IDC, refNode,
  22535. (xmlSchemaTypePtr) matcher->aidc->def,
  22536. "No match found for key-sequence %s of keyref '%s'",
  22537. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22538. refNode->keys, nbFields),
  22539. xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
  22540. FREE_AND_NULL(str);
  22541. FREE_AND_NULL(strB);
  22542. }
  22543. }
  22544. }
  22545. matcher = matcher->next;
  22546. }
  22547. /* TODO: Return an error if any error encountered. */
  22548. return (0);
  22549. }
  22550. /************************************************************************
  22551. * *
  22552. * XML Reader validation code *
  22553. * *
  22554. ************************************************************************/
  22555. static xmlSchemaAttrInfoPtr
  22556. xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
  22557. {
  22558. xmlSchemaAttrInfoPtr iattr;
  22559. /*
  22560. * Grow/create list of attribute infos.
  22561. */
  22562. if (vctxt->attrInfos == NULL) {
  22563. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22564. xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
  22565. vctxt->sizeAttrInfos = 1;
  22566. if (vctxt->attrInfos == NULL) {
  22567. xmlSchemaVErrMemory(vctxt,
  22568. "allocating attribute info list", NULL);
  22569. return (NULL);
  22570. }
  22571. } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
  22572. vctxt->sizeAttrInfos++;
  22573. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22574. xmlRealloc(vctxt->attrInfos,
  22575. vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
  22576. if (vctxt->attrInfos == NULL) {
  22577. xmlSchemaVErrMemory(vctxt,
  22578. "re-allocating attribute info list", NULL);
  22579. return (NULL);
  22580. }
  22581. } else {
  22582. iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
  22583. if (iattr->localName != NULL) {
  22584. VERROR_INT("xmlSchemaGetFreshAttrInfo",
  22585. "attr info not cleared");
  22586. return (NULL);
  22587. }
  22588. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22589. return (iattr);
  22590. }
  22591. /*
  22592. * Create an attribute info.
  22593. */
  22594. iattr = (xmlSchemaAttrInfoPtr)
  22595. xmlMalloc(sizeof(xmlSchemaAttrInfo));
  22596. if (iattr == NULL) {
  22597. xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
  22598. return (NULL);
  22599. }
  22600. memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
  22601. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22602. vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
  22603. return (iattr);
  22604. }
  22605. static int
  22606. xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
  22607. xmlNodePtr attrNode,
  22608. int nodeLine,
  22609. const xmlChar *localName,
  22610. const xmlChar *nsName,
  22611. int ownedNames,
  22612. xmlChar *value,
  22613. int ownedValue)
  22614. {
  22615. xmlSchemaAttrInfoPtr attr;
  22616. attr = xmlSchemaGetFreshAttrInfo(vctxt);
  22617. if (attr == NULL) {
  22618. VERROR_INT("xmlSchemaPushAttribute",
  22619. "calling xmlSchemaGetFreshAttrInfo()");
  22620. return (-1);
  22621. }
  22622. attr->node = attrNode;
  22623. attr->nodeLine = nodeLine;
  22624. attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
  22625. attr->localName = localName;
  22626. attr->nsName = nsName;
  22627. if (ownedNames)
  22628. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  22629. /*
  22630. * Evaluate if it's an XSI attribute.
  22631. */
  22632. if (nsName != NULL) {
  22633. if (xmlStrEqual(localName, BAD_CAST "nil")) {
  22634. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22635. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
  22636. }
  22637. } else if (xmlStrEqual(localName, BAD_CAST "type")) {
  22638. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22639. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
  22640. }
  22641. } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
  22642. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22643. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
  22644. }
  22645. } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
  22646. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22647. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
  22648. }
  22649. } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
  22650. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
  22651. }
  22652. }
  22653. attr->value = value;
  22654. if (ownedValue)
  22655. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  22656. if (attr->metaType != 0)
  22657. attr->state = XML_SCHEMAS_ATTR_META;
  22658. return (0);
  22659. }
  22660. /**
  22661. * xmlSchemaClearElemInfo:
  22662. * @vctxt: the WXS validation context
  22663. * @ielem: the element information item
  22664. */
  22665. static void
  22666. xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
  22667. xmlSchemaNodeInfoPtr ielem)
  22668. {
  22669. ielem->hasKeyrefs = 0;
  22670. ielem->appliedXPath = 0;
  22671. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  22672. FREE_AND_NULL(ielem->localName);
  22673. FREE_AND_NULL(ielem->nsName);
  22674. } else {
  22675. ielem->localName = NULL;
  22676. ielem->nsName = NULL;
  22677. }
  22678. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  22679. FREE_AND_NULL(ielem->value);
  22680. } else {
  22681. ielem->value = NULL;
  22682. }
  22683. if (ielem->val != NULL) {
  22684. /*
  22685. * PSVI TODO: Be careful not to free it when the value is
  22686. * exposed via PSVI.
  22687. */
  22688. xmlSchemaFreeValue(ielem->val);
  22689. ielem->val = NULL;
  22690. }
  22691. if (ielem->idcMatchers != NULL) {
  22692. /*
  22693. * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
  22694. * Does it work?
  22695. */
  22696. xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
  22697. #if 0
  22698. xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
  22699. #endif
  22700. ielem->idcMatchers = NULL;
  22701. }
  22702. if (ielem->idcTable != NULL) {
  22703. /*
  22704. * OPTIMIZE TODO: Use a pool of IDC tables??.
  22705. */
  22706. xmlSchemaIDCFreeIDCTable(ielem->idcTable);
  22707. ielem->idcTable = NULL;
  22708. }
  22709. if (ielem->regexCtxt != NULL) {
  22710. xmlRegFreeExecCtxt(ielem->regexCtxt);
  22711. ielem->regexCtxt = NULL;
  22712. }
  22713. if (ielem->nsBindings != NULL) {
  22714. xmlFree((xmlChar **)ielem->nsBindings);
  22715. ielem->nsBindings = NULL;
  22716. ielem->nbNsBindings = 0;
  22717. ielem->sizeNsBindings = 0;
  22718. }
  22719. }
  22720. /**
  22721. * xmlSchemaGetFreshElemInfo:
  22722. * @vctxt: the schema validation context
  22723. *
  22724. * Creates/reuses and initializes the element info item for
  22725. * the currect tree depth.
  22726. *
  22727. * Returns the element info item or NULL on API or internal errors.
  22728. */
  22729. static xmlSchemaNodeInfoPtr
  22730. xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
  22731. {
  22732. xmlSchemaNodeInfoPtr info = NULL;
  22733. if (vctxt->depth > vctxt->sizeElemInfos) {
  22734. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22735. "inconsistent depth encountered");
  22736. return (NULL);
  22737. }
  22738. if (vctxt->elemInfos == NULL) {
  22739. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22740. xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
  22741. if (vctxt->elemInfos == NULL) {
  22742. xmlSchemaVErrMemory(vctxt,
  22743. "allocating the element info array", NULL);
  22744. return (NULL);
  22745. }
  22746. memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
  22747. vctxt->sizeElemInfos = 10;
  22748. } else if (vctxt->sizeElemInfos <= vctxt->depth) {
  22749. int i = vctxt->sizeElemInfos;
  22750. vctxt->sizeElemInfos *= 2;
  22751. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22752. xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
  22753. sizeof(xmlSchemaNodeInfoPtr));
  22754. if (vctxt->elemInfos == NULL) {
  22755. xmlSchemaVErrMemory(vctxt,
  22756. "re-allocating the element info array", NULL);
  22757. return (NULL);
  22758. }
  22759. /*
  22760. * We need the new memory to be NULLed.
  22761. * TODO: Use memset instead?
  22762. */
  22763. for (; i < vctxt->sizeElemInfos; i++)
  22764. vctxt->elemInfos[i] = NULL;
  22765. } else
  22766. info = vctxt->elemInfos[vctxt->depth];
  22767. if (info == NULL) {
  22768. info = (xmlSchemaNodeInfoPtr)
  22769. xmlMalloc(sizeof(xmlSchemaNodeInfo));
  22770. if (info == NULL) {
  22771. xmlSchemaVErrMemory(vctxt,
  22772. "allocating an element info", NULL);
  22773. return (NULL);
  22774. }
  22775. vctxt->elemInfos[vctxt->depth] = info;
  22776. } else {
  22777. if (info->localName != NULL) {
  22778. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22779. "elem info has not been cleared");
  22780. return (NULL);
  22781. }
  22782. }
  22783. memset(info, 0, sizeof(xmlSchemaNodeInfo));
  22784. info->nodeType = XML_ELEMENT_NODE;
  22785. info->depth = vctxt->depth;
  22786. return (info);
  22787. }
  22788. #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
  22789. #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
  22790. #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
  22791. static int
  22792. xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
  22793. xmlNodePtr node,
  22794. xmlSchemaTypePtr type,
  22795. xmlSchemaValType valType,
  22796. const xmlChar * value,
  22797. xmlSchemaValPtr val,
  22798. unsigned long length,
  22799. int fireErrors)
  22800. {
  22801. int ret, error = 0;
  22802. xmlSchemaTypePtr tmpType;
  22803. xmlSchemaFacetLinkPtr facetLink;
  22804. xmlSchemaFacetPtr facet;
  22805. unsigned long len = 0;
  22806. xmlSchemaWhitespaceValueType ws;
  22807. /*
  22808. * In Libxml2, derived built-in types have currently no explicit facets.
  22809. */
  22810. if (type->type == XML_SCHEMA_TYPE_BASIC)
  22811. return (0);
  22812. /*
  22813. * NOTE: Do not jump away, if the facetSet of the given type is
  22814. * empty: until now, "pattern" and "enumeration" facets of the
  22815. * *base types* need to be checked as well.
  22816. */
  22817. if (type->facetSet == NULL)
  22818. goto pattern_and_enum;
  22819. if (! WXS_IS_ATOMIC(type)) {
  22820. if (WXS_IS_LIST(type))
  22821. goto WXS_IS_LIST;
  22822. else
  22823. goto pattern_and_enum;
  22824. }
  22825. /*
  22826. * Whitespace handling is only of importance for string-based
  22827. * types.
  22828. */
  22829. tmpType = xmlSchemaGetPrimitiveType(type);
  22830. if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
  22831. WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
  22832. ws = xmlSchemaGetWhiteSpaceFacetValue(type);
  22833. } else
  22834. ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
  22835. /*
  22836. * If the value was not computed (for string or
  22837. * anySimpleType based types), then use the provided
  22838. * type.
  22839. */
  22840. if (val == NULL)
  22841. valType = valType;
  22842. else
  22843. valType = xmlSchemaGetValType(val);
  22844. ret = 0;
  22845. for (facetLink = type->facetSet; facetLink != NULL;
  22846. facetLink = facetLink->next) {
  22847. /*
  22848. * Skip the pattern "whiteSpace": it is used to
  22849. * format the character content beforehand.
  22850. */
  22851. switch (facetLink->facet->type) {
  22852. case XML_SCHEMA_FACET_WHITESPACE:
  22853. case XML_SCHEMA_FACET_PATTERN:
  22854. case XML_SCHEMA_FACET_ENUMERATION:
  22855. continue;
  22856. case XML_SCHEMA_FACET_LENGTH:
  22857. case XML_SCHEMA_FACET_MINLENGTH:
  22858. case XML_SCHEMA_FACET_MAXLENGTH:
  22859. ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
  22860. valType, value, val, &len, ws);
  22861. break;
  22862. default:
  22863. ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
  22864. valType, value, val, ws);
  22865. break;
  22866. }
  22867. if (ret < 0) {
  22868. AERROR_INT("xmlSchemaValidateFacets",
  22869. "validating against a atomic type facet");
  22870. return (-1);
  22871. } else if (ret > 0) {
  22872. if (fireErrors)
  22873. xmlSchemaFacetErr(actxt, ret, node,
  22874. value, len, type, facetLink->facet, NULL, NULL, NULL);
  22875. else
  22876. return (ret);
  22877. if (error == 0)
  22878. error = ret;
  22879. }
  22880. ret = 0;
  22881. }
  22882. WXS_IS_LIST:
  22883. if (! WXS_IS_LIST(type))
  22884. goto pattern_and_enum;
  22885. /*
  22886. * "length", "minLength" and "maxLength" of list types.
  22887. */
  22888. ret = 0;
  22889. for (facetLink = type->facetSet; facetLink != NULL;
  22890. facetLink = facetLink->next) {
  22891. switch (facetLink->facet->type) {
  22892. case XML_SCHEMA_FACET_LENGTH:
  22893. case XML_SCHEMA_FACET_MINLENGTH:
  22894. case XML_SCHEMA_FACET_MAXLENGTH:
  22895. ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
  22896. value, length, NULL);
  22897. break;
  22898. default:
  22899. continue;
  22900. }
  22901. if (ret < 0) {
  22902. AERROR_INT("xmlSchemaValidateFacets",
  22903. "validating against a list type facet");
  22904. return (-1);
  22905. } else if (ret > 0) {
  22906. if (fireErrors)
  22907. xmlSchemaFacetErr(actxt, ret, node,
  22908. value, length, type, facetLink->facet, NULL, NULL, NULL);
  22909. else
  22910. return (ret);
  22911. if (error == 0)
  22912. error = ret;
  22913. }
  22914. ret = 0;
  22915. }
  22916. pattern_and_enum:
  22917. if (error >= 0) {
  22918. int found = 0;
  22919. /*
  22920. * Process enumerations. Facet values are in the value space
  22921. * of the defining type's base type. This seems to be a bug in the
  22922. * XML Schema 1.0 spec. Use the whitespace type of the base type.
  22923. * Only the first set of enumerations in the ancestor-or-self axis
  22924. * is used for validation.
  22925. */
  22926. ret = 0;
  22927. tmpType = type;
  22928. do {
  22929. for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
  22930. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  22931. continue;
  22932. found = 1;
  22933. ret = xmlSchemaAreValuesEqual(facet->val, val);
  22934. if (ret == 1)
  22935. break;
  22936. else if (ret < 0) {
  22937. AERROR_INT("xmlSchemaValidateFacets",
  22938. "validating against an enumeration facet");
  22939. return (-1);
  22940. }
  22941. }
  22942. if (ret != 0)
  22943. break;
  22944. /*
  22945. * Break on the first set of enumerations. Any additional
  22946. * enumerations which might be existent on the ancestors
  22947. * of the current type are restricted by this set; thus
  22948. * *must* *not* be taken into account.
  22949. */
  22950. if (found)
  22951. break;
  22952. tmpType = tmpType->baseType;
  22953. } while ((tmpType != NULL) &&
  22954. (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  22955. if (found && (ret == 0)) {
  22956. ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
  22957. if (fireErrors) {
  22958. xmlSchemaFacetErr(actxt, ret, node,
  22959. value, 0, type, NULL, NULL, NULL, NULL);
  22960. } else
  22961. return (ret);
  22962. if (error == 0)
  22963. error = ret;
  22964. }
  22965. }
  22966. if (error >= 0) {
  22967. int found;
  22968. /*
  22969. * Process patters. Pattern facets are ORed at type level
  22970. * and ANDed if derived. Walk the base type axis.
  22971. */
  22972. tmpType = type;
  22973. facet = NULL;
  22974. do {
  22975. found = 0;
  22976. for (facetLink = tmpType->facetSet; facetLink != NULL;
  22977. facetLink = facetLink->next) {
  22978. if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
  22979. continue;
  22980. found = 1;
  22981. /*
  22982. * NOTE that for patterns, @value needs to be the
  22983. * normalized vaule.
  22984. */
  22985. ret = xmlRegexpExec(facetLink->facet->regexp, value);
  22986. if (ret == 1)
  22987. break;
  22988. else if (ret < 0) {
  22989. AERROR_INT("xmlSchemaValidateFacets",
  22990. "validating against a pattern facet");
  22991. return (-1);
  22992. } else {
  22993. /*
  22994. * Save the last non-validating facet.
  22995. */
  22996. facet = facetLink->facet;
  22997. }
  22998. }
  22999. if (found && (ret != 1)) {
  23000. ret = XML_SCHEMAV_CVC_PATTERN_VALID;
  23001. if (fireErrors) {
  23002. xmlSchemaFacetErr(actxt, ret, node,
  23003. value, 0, type, facet, NULL, NULL, NULL);
  23004. } else
  23005. return (ret);
  23006. if (error == 0)
  23007. error = ret;
  23008. break;
  23009. }
  23010. tmpType = tmpType->baseType;
  23011. } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23012. }
  23013. return (error);
  23014. }
  23015. static xmlChar *
  23016. xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
  23017. const xmlChar *value)
  23018. {
  23019. switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
  23020. case XML_SCHEMA_WHITESPACE_COLLAPSE:
  23021. return (xmlSchemaCollapseString(value));
  23022. case XML_SCHEMA_WHITESPACE_REPLACE:
  23023. return (xmlSchemaWhiteSpaceReplace(value));
  23024. default:
  23025. return (NULL);
  23026. }
  23027. }
  23028. static int
  23029. xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
  23030. const xmlChar *value,
  23031. xmlSchemaValPtr *val,
  23032. int valNeeded)
  23033. {
  23034. int ret;
  23035. const xmlChar *nsName;
  23036. xmlChar *local, *prefix = NULL;
  23037. ret = xmlValidateQName(value, 1);
  23038. if (ret != 0) {
  23039. if (ret == -1) {
  23040. VERROR_INT("xmlSchemaValidateQName",
  23041. "calling xmlValidateQName()");
  23042. return (-1);
  23043. }
  23044. return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
  23045. }
  23046. /*
  23047. * NOTE: xmlSplitQName2 will always return a duplicated
  23048. * strings.
  23049. */
  23050. local = xmlSplitQName2(value, &prefix);
  23051. if (local == NULL)
  23052. local = xmlStrdup(value);
  23053. /*
  23054. * OPTIMIZE TODO: Use flags for:
  23055. * - is there any namespace binding?
  23056. * - is there a default namespace?
  23057. */
  23058. nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23059. if (prefix != NULL) {
  23060. xmlFree(prefix);
  23061. /*
  23062. * A namespace must be found if the prefix is
  23063. * NOT NULL.
  23064. */
  23065. if (nsName == NULL) {
  23066. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23067. xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
  23068. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23069. "The QName value '%s' has no "
  23070. "corresponding namespace declaration in "
  23071. "scope", value, NULL);
  23072. if (local != NULL)
  23073. xmlFree(local);
  23074. return (ret);
  23075. }
  23076. }
  23077. if (valNeeded && val) {
  23078. if (nsName != NULL)
  23079. *val = xmlSchemaNewQNameValue(
  23080. BAD_CAST xmlStrdup(nsName), BAD_CAST local);
  23081. else
  23082. *val = xmlSchemaNewQNameValue(NULL,
  23083. BAD_CAST local);
  23084. } else
  23085. xmlFree(local);
  23086. return (0);
  23087. }
  23088. /*
  23089. * cvc-simple-type
  23090. */
  23091. static int
  23092. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  23093. xmlNodePtr node,
  23094. xmlSchemaTypePtr type,
  23095. const xmlChar *value,
  23096. xmlSchemaValPtr *retVal,
  23097. int fireErrors,
  23098. int normalize,
  23099. int isNormalized)
  23100. {
  23101. int ret = 0, valNeeded = (retVal) ? 1 : 0;
  23102. xmlSchemaValPtr val = NULL;
  23103. /* xmlSchemaWhitespaceValueType ws; */
  23104. xmlChar *normValue = NULL;
  23105. #define NORMALIZE(atype) \
  23106. if ((! isNormalized) && \
  23107. (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
  23108. normValue = xmlSchemaNormalizeValue(atype, value); \
  23109. if (normValue != NULL) \
  23110. value = normValue; \
  23111. isNormalized = 1; \
  23112. }
  23113. if ((retVal != NULL) && (*retVal != NULL)) {
  23114. xmlSchemaFreeValue(*retVal);
  23115. *retVal = NULL;
  23116. }
  23117. /*
  23118. * 3.14.4 Simple Type Definition Validation Rules
  23119. * Validation Rule: String Valid
  23120. */
  23121. /*
  23122. * 1 It is schema-valid with respect to that definition as defined
  23123. * by Datatype Valid in [XML Schemas: Datatypes].
  23124. */
  23125. /*
  23126. * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
  23127. * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
  23128. * the string must be a �declared entity name�.
  23129. */
  23130. /*
  23131. * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
  23132. * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
  23133. * then every whitespace-delimited substring of the string must be a �declared
  23134. * entity name�.
  23135. */
  23136. /*
  23137. * 2.3 otherwise no further condition applies.
  23138. */
  23139. if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
  23140. valNeeded = 1;
  23141. if (value == NULL)
  23142. value = BAD_CAST "";
  23143. if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
  23144. xmlSchemaTypePtr biType; /* The built-in type. */
  23145. /*
  23146. * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
  23147. * a literal in the �lexical space� of {base type definition}"
  23148. */
  23149. /*
  23150. * Whitespace-normalize.
  23151. */
  23152. NORMALIZE(type);
  23153. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  23154. /*
  23155. * Get the built-in type.
  23156. */
  23157. biType = type->baseType;
  23158. while ((biType != NULL) &&
  23159. (biType->type != XML_SCHEMA_TYPE_BASIC))
  23160. biType = biType->baseType;
  23161. if (biType == NULL) {
  23162. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23163. "could not get the built-in type");
  23164. goto internal_error;
  23165. }
  23166. } else
  23167. biType = type;
  23168. /*
  23169. * NOTATIONs need to be processed here, since they need
  23170. * to lookup in the hashtable of NOTATION declarations of the schema.
  23171. */
  23172. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  23173. switch (biType->builtInType) {
  23174. case XML_SCHEMAS_NOTATION:
  23175. ret = xmlSchemaValidateNotation(
  23176. (xmlSchemaValidCtxtPtr) actxt,
  23177. ((xmlSchemaValidCtxtPtr) actxt)->schema,
  23178. NULL, value, &val, valNeeded);
  23179. break;
  23180. case XML_SCHEMAS_QNAME:
  23181. ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
  23182. value, &val, valNeeded);
  23183. break;
  23184. default:
  23185. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23186. if (valNeeded)
  23187. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23188. value, &val, node);
  23189. else
  23190. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23191. value, NULL, node);
  23192. break;
  23193. }
  23194. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  23195. switch (biType->builtInType) {
  23196. case XML_SCHEMAS_NOTATION:
  23197. ret = xmlSchemaValidateNotation(NULL,
  23198. ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
  23199. value, &val, valNeeded);
  23200. break;
  23201. default:
  23202. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23203. if (valNeeded)
  23204. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23205. value, &val, node);
  23206. else
  23207. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23208. value, NULL, node);
  23209. break;
  23210. }
  23211. } else {
  23212. /*
  23213. * Validation via a public API is not implemented yet.
  23214. */
  23215. TODO
  23216. goto internal_error;
  23217. }
  23218. if (ret != 0) {
  23219. if (ret < 0) {
  23220. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23221. "validating against a built-in type");
  23222. goto internal_error;
  23223. }
  23224. if (WXS_IS_LIST(type))
  23225. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23226. else
  23227. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23228. }
  23229. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23230. /*
  23231. * Check facets.
  23232. */
  23233. ret = xmlSchemaValidateFacets(actxt, node, type,
  23234. (xmlSchemaValType) biType->builtInType, value, val,
  23235. 0, fireErrors);
  23236. if (ret != 0) {
  23237. if (ret < 0) {
  23238. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23239. "validating facets of atomic simple type");
  23240. goto internal_error;
  23241. }
  23242. if (WXS_IS_LIST(type))
  23243. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23244. else
  23245. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23246. }
  23247. }
  23248. if (fireErrors && (ret > 0))
  23249. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23250. } else if (WXS_IS_LIST(type)) {
  23251. xmlSchemaTypePtr itemType;
  23252. const xmlChar *cur, *end;
  23253. xmlChar *tmpValue = NULL;
  23254. unsigned long len = 0;
  23255. xmlSchemaValPtr prevVal = NULL, curVal = NULL;
  23256. /* 1.2.2 if {variety} is �list� then the string must be a sequence
  23257. * of white space separated tokens, each of which �match�es a literal
  23258. * in the �lexical space� of {item type definition}
  23259. */
  23260. /*
  23261. * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
  23262. * the list type has an enum or pattern facet.
  23263. */
  23264. NORMALIZE(type);
  23265. /*
  23266. * VAL TODO: Optimize validation of empty values.
  23267. * VAL TODO: We do not have computed values for lists.
  23268. */
  23269. itemType = WXS_LIST_ITEMTYPE(type);
  23270. cur = value;
  23271. do {
  23272. while (IS_BLANK_CH(*cur))
  23273. cur++;
  23274. end = cur;
  23275. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  23276. end++;
  23277. if (end == cur)
  23278. break;
  23279. tmpValue = xmlStrndup(cur, end - cur);
  23280. len++;
  23281. if (valNeeded)
  23282. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23283. tmpValue, &curVal, fireErrors, 0, 1);
  23284. else
  23285. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23286. tmpValue, NULL, fireErrors, 0, 1);
  23287. FREE_AND_NULL(tmpValue);
  23288. if (curVal != NULL) {
  23289. /*
  23290. * Add to list of computed values.
  23291. */
  23292. if (val == NULL)
  23293. val = curVal;
  23294. else
  23295. xmlSchemaValueAppend(prevVal, curVal);
  23296. prevVal = curVal;
  23297. curVal = NULL;
  23298. }
  23299. if (ret != 0) {
  23300. if (ret < 0) {
  23301. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23302. "validating an item of list simple type");
  23303. goto internal_error;
  23304. }
  23305. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23306. break;
  23307. }
  23308. cur = end;
  23309. } while (*cur != 0);
  23310. FREE_AND_NULL(tmpValue);
  23311. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23312. /*
  23313. * Apply facets (pattern, enumeration).
  23314. */
  23315. ret = xmlSchemaValidateFacets(actxt, node, type,
  23316. XML_SCHEMAS_UNKNOWN, value, val,
  23317. len, fireErrors);
  23318. if (ret != 0) {
  23319. if (ret < 0) {
  23320. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23321. "validating facets of list simple type");
  23322. goto internal_error;
  23323. }
  23324. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23325. }
  23326. }
  23327. if (fireErrors && (ret > 0)) {
  23328. /*
  23329. * Report the normalized value.
  23330. */
  23331. normalize = 1;
  23332. NORMALIZE(type);
  23333. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23334. }
  23335. } else if (WXS_IS_UNION(type)) {
  23336. xmlSchemaTypeLinkPtr memberLink;
  23337. /*
  23338. * TODO: For all datatypes �derived� by �union� whiteSpace does
  23339. * not apply directly; however, the normalization behavior of �union�
  23340. * types is controlled by the value of whiteSpace on that one of the
  23341. * �memberTypes� against which the �union� is successfully validated.
  23342. *
  23343. * This means that the value is normalized by the first validating
  23344. * member type, then the facets of the union type are applied. This
  23345. * needs changing of the value!
  23346. */
  23347. /*
  23348. * 1.2.3 if {variety} is �union� then the string must �match� a
  23349. * literal in the �lexical space� of at least one member of
  23350. * {member type definitions}
  23351. */
  23352. memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
  23353. if (memberLink == NULL) {
  23354. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23355. "union simple type has no member types");
  23356. goto internal_error;
  23357. }
  23358. /*
  23359. * Always normalize union type values, since we currently
  23360. * cannot store the whitespace information with the value
  23361. * itself; otherwise a later value-comparison would be
  23362. * not possible.
  23363. */
  23364. while (memberLink != NULL) {
  23365. if (valNeeded)
  23366. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23367. memberLink->type, value, &val, 0, 1, 0);
  23368. else
  23369. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23370. memberLink->type, value, NULL, 0, 1, 0);
  23371. if (ret <= 0)
  23372. break;
  23373. memberLink = memberLink->next;
  23374. }
  23375. if (ret != 0) {
  23376. if (ret < 0) {
  23377. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23378. "validating members of union simple type");
  23379. goto internal_error;
  23380. }
  23381. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23382. }
  23383. /*
  23384. * Apply facets (pattern, enumeration).
  23385. */
  23386. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23387. /*
  23388. * The normalization behavior of �union� types is controlled by
  23389. * the value of whiteSpace on that one of the �memberTypes�
  23390. * against which the �union� is successfully validated.
  23391. */
  23392. NORMALIZE(memberLink->type);
  23393. ret = xmlSchemaValidateFacets(actxt, node, type,
  23394. XML_SCHEMAS_UNKNOWN, value, val,
  23395. 0, fireErrors);
  23396. if (ret != 0) {
  23397. if (ret < 0) {
  23398. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23399. "validating facets of union simple type");
  23400. goto internal_error;
  23401. }
  23402. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23403. }
  23404. }
  23405. if (fireErrors && (ret > 0))
  23406. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23407. }
  23408. if (normValue != NULL)
  23409. xmlFree(normValue);
  23410. if (ret == 0) {
  23411. if (retVal != NULL)
  23412. *retVal = val;
  23413. else if (val != NULL)
  23414. xmlSchemaFreeValue(val);
  23415. } else if (val != NULL)
  23416. xmlSchemaFreeValue(val);
  23417. return (ret);
  23418. internal_error:
  23419. if (normValue != NULL)
  23420. xmlFree(normValue);
  23421. if (val != NULL)
  23422. xmlSchemaFreeValue(val);
  23423. return (-1);
  23424. }
  23425. static int
  23426. xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
  23427. const xmlChar *value,
  23428. const xmlChar **nsName,
  23429. const xmlChar **localName)
  23430. {
  23431. int ret = 0;
  23432. if ((nsName == NULL) || (localName == NULL))
  23433. return (-1);
  23434. *nsName = NULL;
  23435. *localName = NULL;
  23436. ret = xmlValidateQName(value, 1);
  23437. if (ret == -1)
  23438. return (-1);
  23439. if (ret > 0) {
  23440. xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
  23441. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23442. value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
  23443. return (1);
  23444. }
  23445. {
  23446. xmlChar *local = NULL;
  23447. xmlChar *prefix;
  23448. /*
  23449. * NOTE: xmlSplitQName2 will return a duplicated
  23450. * string.
  23451. */
  23452. local = xmlSplitQName2(value, &prefix);
  23453. if (local == NULL)
  23454. *localName = xmlDictLookup(vctxt->dict, value, -1);
  23455. else {
  23456. *localName = xmlDictLookup(vctxt->dict, local, -1);
  23457. xmlFree(local);
  23458. }
  23459. *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23460. if (prefix != NULL) {
  23461. xmlFree(prefix);
  23462. /*
  23463. * A namespace must be found if the prefix is NOT NULL.
  23464. */
  23465. if (*nsName == NULL) {
  23466. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23467. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23468. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23469. "The QName value '%s' has no "
  23470. "corresponding namespace declaration in scope",
  23471. value, NULL);
  23472. return (2);
  23473. }
  23474. }
  23475. }
  23476. return (0);
  23477. }
  23478. static int
  23479. xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
  23480. xmlSchemaAttrInfoPtr iattr,
  23481. xmlSchemaTypePtr *localType,
  23482. xmlSchemaElementPtr elemDecl)
  23483. {
  23484. int ret = 0;
  23485. /*
  23486. * cvc-elt (3.3.4) : (4)
  23487. * AND
  23488. * Schema-Validity Assessment (Element) (cvc-assess-elt)
  23489. * (1.2.1.2.1) - (1.2.1.2.4)
  23490. * Handle 'xsi:type'.
  23491. */
  23492. if (localType == NULL)
  23493. return (-1);
  23494. *localType = NULL;
  23495. if (iattr == NULL)
  23496. return (0);
  23497. else {
  23498. const xmlChar *nsName = NULL, *local = NULL;
  23499. /*
  23500. * TODO: We should report a *warning* that the type was overriden
  23501. * by the instance.
  23502. */
  23503. ACTIVATE_ATTRIBUTE(iattr);
  23504. /*
  23505. * (cvc-elt) (3.3.4) : (4.1)
  23506. * (cvc-assess-elt) (1.2.1.2.2)
  23507. */
  23508. ret = xmlSchemaVExpandQName(vctxt, iattr->value,
  23509. &nsName, &local);
  23510. if (ret != 0) {
  23511. if (ret < 0) {
  23512. VERROR_INT("xmlSchemaValidateElementByDeclaration",
  23513. "calling xmlSchemaQNameExpand() to validate the "
  23514. "attribute 'xsi:type'");
  23515. goto internal_error;
  23516. }
  23517. goto exit;
  23518. }
  23519. /*
  23520. * (cvc-elt) (3.3.4) : (4.2)
  23521. * (cvc-assess-elt) (1.2.1.2.3)
  23522. */
  23523. *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
  23524. if (*localType == NULL) {
  23525. xmlChar *str = NULL;
  23526. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23527. XML_SCHEMAV_CVC_ELT_4_2, NULL,
  23528. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23529. "The QName value '%s' of the xsi:type attribute does not "
  23530. "resolve to a type definition",
  23531. xmlSchemaFormatQName(&str, nsName, local), NULL);
  23532. FREE_AND_NULL(str);
  23533. ret = vctxt->err;
  23534. goto exit;
  23535. }
  23536. if (elemDecl != NULL) {
  23537. int set = 0;
  23538. /*
  23539. * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
  23540. * "The �local type definition� must be validly
  23541. * derived from the {type definition} given the union of
  23542. * the {disallowed substitutions} and the {type definition}'s
  23543. * {prohibited substitutions}, as defined in
  23544. * Type Derivation OK (Complex) (�3.4.6)
  23545. * (if it is a complex type definition),
  23546. * or given {disallowed substitutions} as defined in Type
  23547. * Derivation OK (Simple) (�3.14.6) (if it is a simple type
  23548. * definition)."
  23549. *
  23550. * {disallowed substitutions}: the "block" on the element decl.
  23551. * {prohibited substitutions}: the "block" on the type def.
  23552. */
  23553. /*
  23554. * OPTIMIZE TODO: We could map types already evaluated
  23555. * to be validly derived from other types to avoid checking
  23556. * this over and over for the same types.
  23557. */
  23558. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
  23559. (elemDecl->subtypes->flags &
  23560. XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
  23561. set |= SUBSET_EXTENSION;
  23562. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
  23563. (elemDecl->subtypes->flags &
  23564. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
  23565. set |= SUBSET_RESTRICTION;
  23566. /*
  23567. * REMOVED and CHANGED since this produced a parser context
  23568. * which adds to the string dict of the schema. So this would
  23569. * change the schema and we don't want this. We don't need
  23570. * the parser context anymore.
  23571. *
  23572. * if ((vctxt->pctxt == NULL) &&
  23573. * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  23574. * return (-1);
  23575. */
  23576. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
  23577. elemDecl->subtypes, set) != 0) {
  23578. xmlChar *str = NULL;
  23579. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23580. XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
  23581. "The type definition '%s', specified by xsi:type, is "
  23582. "blocked or not validly derived from the type definition "
  23583. "of the element declaration",
  23584. xmlSchemaFormatQName(&str,
  23585. (*localType)->targetNamespace,
  23586. (*localType)->name),
  23587. NULL);
  23588. FREE_AND_NULL(str);
  23589. ret = vctxt->err;
  23590. *localType = NULL;
  23591. }
  23592. }
  23593. }
  23594. exit:
  23595. ACTIVATE_ELEM;
  23596. return (ret);
  23597. internal_error:
  23598. ACTIVATE_ELEM;
  23599. return (-1);
  23600. }
  23601. static int
  23602. xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
  23603. {
  23604. xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
  23605. xmlSchemaTypePtr actualType;
  23606. /*
  23607. * cvc-elt (3.3.4) : 1
  23608. */
  23609. if (elemDecl == NULL) {
  23610. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
  23611. "No matching declaration available");
  23612. return (vctxt->err);
  23613. }
  23614. actualType = WXS_ELEM_TYPEDEF(elemDecl);
  23615. /*
  23616. * cvc-elt (3.3.4) : 2
  23617. */
  23618. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
  23619. VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
  23620. "The element declaration is abstract");
  23621. return (vctxt->err);
  23622. }
  23623. if (actualType == NULL) {
  23624. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23625. "The type definition is absent");
  23626. return (XML_SCHEMAV_CVC_TYPE_1);
  23627. }
  23628. if (vctxt->nbAttrInfos != 0) {
  23629. int ret;
  23630. xmlSchemaAttrInfoPtr iattr;
  23631. /*
  23632. * cvc-elt (3.3.4) : 3
  23633. * Handle 'xsi:nil'.
  23634. */
  23635. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23636. XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
  23637. if (iattr) {
  23638. ACTIVATE_ATTRIBUTE(iattr);
  23639. /*
  23640. * Validate the value.
  23641. */
  23642. ret = xmlSchemaVCheckCVCSimpleType(
  23643. ACTXT_CAST vctxt, NULL,
  23644. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  23645. iattr->value, &(iattr->val), 1, 0, 0);
  23646. ACTIVATE_ELEM;
  23647. if (ret < 0) {
  23648. VERROR_INT("xmlSchemaValidateElemDecl",
  23649. "calling xmlSchemaVCheckCVCSimpleType() to "
  23650. "validate the attribute 'xsi:nil'");
  23651. return (-1);
  23652. }
  23653. if (ret == 0) {
  23654. if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
  23655. /*
  23656. * cvc-elt (3.3.4) : 3.1
  23657. */
  23658. VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
  23659. "The element is not 'nillable'");
  23660. /* Does not return an error on purpose. */
  23661. } else {
  23662. if (xmlSchemaValueGetAsBoolean(iattr->val)) {
  23663. /*
  23664. * cvc-elt (3.3.4) : 3.2.2
  23665. */
  23666. if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
  23667. (elemDecl->value != NULL)) {
  23668. VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
  23669. "The element cannot be 'nilled' because "
  23670. "there is a fixed value constraint defined "
  23671. "for it");
  23672. /* Does not return an error on purpose. */
  23673. } else
  23674. vctxt->inode->flags |=
  23675. XML_SCHEMA_ELEM_INFO_NILLED;
  23676. }
  23677. }
  23678. }
  23679. }
  23680. /*
  23681. * cvc-elt (3.3.4) : 4
  23682. * Handle 'xsi:type'.
  23683. */
  23684. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23685. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  23686. if (iattr) {
  23687. xmlSchemaTypePtr localType = NULL;
  23688. ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
  23689. elemDecl);
  23690. if (ret != 0) {
  23691. if (ret == -1) {
  23692. VERROR_INT("xmlSchemaValidateElemDecl",
  23693. "calling xmlSchemaProcessXSIType() to "
  23694. "process the attribute 'xsi:type'");
  23695. return (-1);
  23696. }
  23697. /* Does not return an error on purpose. */
  23698. }
  23699. if (localType != NULL) {
  23700. vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
  23701. actualType = localType;
  23702. }
  23703. }
  23704. }
  23705. /*
  23706. * IDC: Register identity-constraint XPath matchers.
  23707. */
  23708. if ((elemDecl->idcs != NULL) &&
  23709. (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
  23710. return (-1);
  23711. /*
  23712. * No actual type definition.
  23713. */
  23714. if (actualType == NULL) {
  23715. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23716. "The type definition is absent");
  23717. return (XML_SCHEMAV_CVC_TYPE_1);
  23718. }
  23719. /*
  23720. * Remember the actual type definition.
  23721. */
  23722. vctxt->inode->typeDef = actualType;
  23723. return (0);
  23724. }
  23725. static int
  23726. xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
  23727. {
  23728. xmlSchemaAttrInfoPtr iattr;
  23729. int ret = 0, i;
  23730. /*
  23731. * SPEC cvc-type (3.1.1)
  23732. * "The attributes of must be empty, excepting those whose namespace
  23733. * name is identical to http://www.w3.org/2001/XMLSchema-instance and
  23734. * whose local name is one of type, nil, schemaLocation or
  23735. * noNamespaceSchemaLocation."
  23736. */
  23737. if (vctxt->nbAttrInfos == 0)
  23738. return (0);
  23739. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23740. iattr = vctxt->attrInfos[i];
  23741. if (! iattr->metaType) {
  23742. ACTIVATE_ATTRIBUTE(iattr)
  23743. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  23744. XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
  23745. ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
  23746. }
  23747. }
  23748. ACTIVATE_ELEM
  23749. return (ret);
  23750. }
  23751. /*
  23752. * Cleanup currently used attribute infos.
  23753. */
  23754. static void
  23755. xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
  23756. {
  23757. int i;
  23758. xmlSchemaAttrInfoPtr attr;
  23759. if (vctxt->nbAttrInfos == 0)
  23760. return;
  23761. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23762. attr = vctxt->attrInfos[i];
  23763. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  23764. if (attr->localName != NULL)
  23765. xmlFree((xmlChar *) attr->localName);
  23766. if (attr->nsName != NULL)
  23767. xmlFree((xmlChar *) attr->nsName);
  23768. }
  23769. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  23770. if (attr->value != NULL)
  23771. xmlFree((xmlChar *) attr->value);
  23772. }
  23773. if (attr->val != NULL) {
  23774. xmlSchemaFreeValue(attr->val);
  23775. attr->val = NULL;
  23776. }
  23777. memset(attr, 0, sizeof(xmlSchemaAttrInfo));
  23778. }
  23779. vctxt->nbAttrInfos = 0;
  23780. }
  23781. /*
  23782. * 3.4.4 Complex Type Definition Validation Rules
  23783. * Element Locally Valid (Complex Type) (cvc-complex-type)
  23784. * 3.2.4 Attribute Declaration Validation Rules
  23785. * Validation Rule: Attribute Locally Valid (cvc-attribute)
  23786. * Attribute Locally Valid (Use) (cvc-au)
  23787. *
  23788. * Only "assessed" attribute information items will be visible to
  23789. * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
  23790. */
  23791. static int
  23792. xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
  23793. {
  23794. xmlSchemaTypePtr type = vctxt->inode->typeDef;
  23795. xmlSchemaItemListPtr attrUseList;
  23796. xmlSchemaAttributeUsePtr attrUse = NULL;
  23797. xmlSchemaAttributePtr attrDecl = NULL;
  23798. xmlSchemaAttrInfoPtr iattr, tmpiattr;
  23799. int i, j, found, nbAttrs, nbUses;
  23800. int xpathRes = 0, res, wildIDs = 0, fixed;
  23801. xmlNodePtr defAttrOwnerElem = NULL;
  23802. /*
  23803. * SPEC (cvc-attribute)
  23804. * (1) "The declaration must not be �absent� (see Missing
  23805. * Sub-components (�5.3) for how this can fail to be
  23806. * the case)."
  23807. * (2) "Its {type definition} must not be absent."
  23808. *
  23809. * NOTE (1) + (2): This is not handled here, since we currently do not
  23810. * allow validation against schemas which have missing sub-components.
  23811. *
  23812. * SPEC (cvc-complex-type)
  23813. * (3) "For each attribute information item in the element information
  23814. * item's [attributes] excepting those whose [namespace name] is
  23815. * identical to http://www.w3.org/2001/XMLSchema-instance and whose
  23816. * [local name] is one of type, nil, schemaLocation or
  23817. * noNamespaceSchemaLocation, the appropriate case among the following
  23818. * must be true:
  23819. *
  23820. */
  23821. attrUseList = (xmlSchemaItemListPtr) type->attrUses;
  23822. /*
  23823. * @nbAttrs is the number of attributes present in the instance.
  23824. */
  23825. nbAttrs = vctxt->nbAttrInfos;
  23826. if (attrUseList != NULL)
  23827. nbUses = attrUseList->nbItems;
  23828. else
  23829. nbUses = 0;
  23830. for (i = 0; i < nbUses; i++) {
  23831. found = 0;
  23832. attrUse = attrUseList->items[i];
  23833. attrDecl = WXS_ATTRUSE_DECL(attrUse);
  23834. for (j = 0; j < nbAttrs; j++) {
  23835. iattr = vctxt->attrInfos[j];
  23836. /*
  23837. * SPEC (cvc-complex-type) (3)
  23838. * Skip meta attributes.
  23839. */
  23840. if (iattr->metaType)
  23841. continue;
  23842. if (iattr->localName[0] != attrDecl->name[0])
  23843. continue;
  23844. if (!xmlStrEqual(iattr->localName, attrDecl->name))
  23845. continue;
  23846. if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
  23847. continue;
  23848. found = 1;
  23849. /*
  23850. * SPEC (cvc-complex-type)
  23851. * (3.1) "If there is among the {attribute uses} an attribute
  23852. * use with an {attribute declaration} whose {name} matches
  23853. * the attribute information item's [local name] and whose
  23854. * {target namespace} is identical to the attribute information
  23855. * item's [namespace name] (where an �absent� {target namespace}
  23856. * is taken to be identical to a [namespace name] with no value),
  23857. * then the attribute information must be �valid� with respect
  23858. * to that attribute use as per Attribute Locally Valid (Use)
  23859. * (�3.5.4). In this case the {attribute declaration} of that
  23860. * attribute use is the �context-determined declaration� for the
  23861. * attribute information item with respect to Schema-Validity
  23862. * Assessment (Attribute) (�3.2.4) and
  23863. * Assessment Outcome (Attribute) (�3.2.5).
  23864. */
  23865. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  23866. iattr->use = attrUse;
  23867. /*
  23868. * Context-determined declaration.
  23869. */
  23870. iattr->decl = attrDecl;
  23871. iattr->typeDef = attrDecl->subtypes;
  23872. break;
  23873. }
  23874. if (found)
  23875. continue;
  23876. if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
  23877. /*
  23878. * Handle non-existent, required attributes.
  23879. *
  23880. * SPEC (cvc-complex-type)
  23881. * (4) "The {attribute declaration} of each attribute use in
  23882. * the {attribute uses} whose {required} is true matches one
  23883. * of the attribute information items in the element information
  23884. * item's [attributes] as per clause 3.1 above."
  23885. */
  23886. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23887. if (tmpiattr == NULL) {
  23888. VERROR_INT(
  23889. "xmlSchemaVAttributesComplex",
  23890. "calling xmlSchemaGetFreshAttrInfo()");
  23891. return (-1);
  23892. }
  23893. tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
  23894. tmpiattr->use = attrUse;
  23895. tmpiattr->decl = attrDecl;
  23896. } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  23897. ((attrUse->defValue != NULL) ||
  23898. (attrDecl->defValue != NULL))) {
  23899. /*
  23900. * Handle non-existent, optional, default/fixed attributes.
  23901. */
  23902. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23903. if (tmpiattr == NULL) {
  23904. VERROR_INT(
  23905. "xmlSchemaVAttributesComplex",
  23906. "calling xmlSchemaGetFreshAttrInfo()");
  23907. return (-1);
  23908. }
  23909. tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
  23910. tmpiattr->use = attrUse;
  23911. tmpiattr->decl = attrDecl;
  23912. tmpiattr->typeDef = attrDecl->subtypes;
  23913. tmpiattr->localName = attrDecl->name;
  23914. tmpiattr->nsName = attrDecl->targetNamespace;
  23915. }
  23916. }
  23917. if (vctxt->nbAttrInfos == 0)
  23918. return (0);
  23919. /*
  23920. * Validate against the wildcard.
  23921. */
  23922. if (type->attributeWildcard != NULL) {
  23923. /*
  23924. * SPEC (cvc-complex-type)
  23925. * (3.2.1) "There must be an {attribute wildcard}."
  23926. */
  23927. for (i = 0; i < nbAttrs; i++) {
  23928. iattr = vctxt->attrInfos[i];
  23929. /*
  23930. * SPEC (cvc-complex-type) (3)
  23931. * Skip meta attributes.
  23932. */
  23933. if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
  23934. continue;
  23935. /*
  23936. * SPEC (cvc-complex-type)
  23937. * (3.2.2) "The attribute information item must be �valid� with
  23938. * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
  23939. *
  23940. * SPEC Item Valid (Wildcard) (cvc-wildcard)
  23941. * "... its [namespace name] must be �valid� with respect to
  23942. * the wildcard constraint, as defined in Wildcard allows
  23943. * Namespace Name (�3.10.4)."
  23944. */
  23945. if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
  23946. iattr->nsName) == 0) {
  23947. /*
  23948. * Handle processContents.
  23949. *
  23950. * SPEC (cvc-wildcard):
  23951. * processContents | context-determined declaration:
  23952. * "strict" "mustFind"
  23953. * "lax" "none"
  23954. * "skip" "skip"
  23955. */
  23956. if (type->attributeWildcard->processContents ==
  23957. XML_SCHEMAS_ANY_SKIP) {
  23958. /*
  23959. * context-determined declaration = "skip"
  23960. *
  23961. * SPEC PSVI Assessment Outcome (Attribute)
  23962. * [validity] = "notKnown"
  23963. * [validation attempted] = "none"
  23964. */
  23965. iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
  23966. continue;
  23967. }
  23968. /*
  23969. * Find an attribute declaration.
  23970. */
  23971. iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
  23972. iattr->localName, iattr->nsName);
  23973. if (iattr->decl != NULL) {
  23974. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  23975. /*
  23976. * SPEC (cvc-complex-type)
  23977. * (5) "Let [Definition:] the wild IDs be the set of
  23978. * all attribute information item to which clause 3.2
  23979. * applied and whose �validation� resulted in a
  23980. * �context-determined declaration� of mustFind or no
  23981. * �context-determined declaration� at all, and whose
  23982. * [local name] and [namespace name] resolve (as
  23983. * defined by QName resolution (Instance) (�3.15.4)) to
  23984. * an attribute declaration whose {type definition} is
  23985. * or is derived from ID. Then all of the following
  23986. * must be true:"
  23987. */
  23988. iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
  23989. if (xmlSchemaIsDerivedFromBuiltInType(
  23990. iattr->typeDef, XML_SCHEMAS_ID)) {
  23991. /*
  23992. * SPEC (5.1) "There must be no more than one
  23993. * item in �wild IDs�."
  23994. */
  23995. if (wildIDs != 0) {
  23996. /* VAL TODO */
  23997. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
  23998. TODO
  23999. continue;
  24000. }
  24001. wildIDs++;
  24002. /*
  24003. * SPEC (cvc-complex-type)
  24004. * (5.2) "If �wild IDs� is non-empty, there must not
  24005. * be any attribute uses among the {attribute uses}
  24006. * whose {attribute declaration}'s {type definition}
  24007. * is or is derived from ID."
  24008. */
  24009. if (attrUseList != NULL) {
  24010. for (j = 0; j < attrUseList->nbItems; j++) {
  24011. if (xmlSchemaIsDerivedFromBuiltInType(
  24012. WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
  24013. XML_SCHEMAS_ID)) {
  24014. /* URGENT VAL TODO: implement */
  24015. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
  24016. TODO
  24017. break;
  24018. }
  24019. }
  24020. }
  24021. }
  24022. } else if (type->attributeWildcard->processContents ==
  24023. XML_SCHEMAS_ANY_LAX) {
  24024. iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
  24025. /*
  24026. * SPEC PSVI Assessment Outcome (Attribute)
  24027. * [validity] = "notKnown"
  24028. * [validation attempted] = "none"
  24029. */
  24030. } else {
  24031. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
  24032. }
  24033. }
  24034. }
  24035. }
  24036. if (vctxt->nbAttrInfos == 0)
  24037. return (0);
  24038. /*
  24039. * Get the owner element; needed for creation of default attributes.
  24040. * This fixes bug #341337, reported by David Grohmann.
  24041. */
  24042. if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
  24043. xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
  24044. if (ielem && ielem->node && ielem->node->doc)
  24045. defAttrOwnerElem = ielem->node;
  24046. }
  24047. /*
  24048. * Validate values, create default attributes, evaluate IDCs.
  24049. */
  24050. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24051. iattr = vctxt->attrInfos[i];
  24052. /*
  24053. * VAL TODO: Note that we won't try to resolve IDCs to
  24054. * "lax" and "skip" validated attributes. Check what to
  24055. * do in this case.
  24056. */
  24057. if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
  24058. (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
  24059. continue;
  24060. /*
  24061. * VAL TODO: What to do if the type definition is missing?
  24062. */
  24063. if (iattr->typeDef == NULL) {
  24064. iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
  24065. continue;
  24066. }
  24067. ACTIVATE_ATTRIBUTE(iattr);
  24068. fixed = 0;
  24069. xpathRes = 0;
  24070. if (vctxt->xpathStates != NULL) {
  24071. /*
  24072. * Evaluate IDCs.
  24073. */
  24074. xpathRes = xmlSchemaXPathEvaluate(vctxt,
  24075. XML_ATTRIBUTE_NODE);
  24076. if (xpathRes == -1) {
  24077. VERROR_INT("xmlSchemaVAttributesComplex",
  24078. "calling xmlSchemaXPathEvaluate()");
  24079. goto internal_error;
  24080. }
  24081. }
  24082. if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
  24083. /*
  24084. * Default/fixed attributes.
  24085. * We need the value only if we need to resolve IDCs or
  24086. * will create default attributes.
  24087. */
  24088. if ((xpathRes) || (defAttrOwnerElem)) {
  24089. if (iattr->use->defValue != NULL) {
  24090. iattr->value = (xmlChar *) iattr->use->defValue;
  24091. iattr->val = iattr->use->defVal;
  24092. } else {
  24093. iattr->value = (xmlChar *) iattr->decl->defValue;
  24094. iattr->val = iattr->decl->defVal;
  24095. }
  24096. /*
  24097. * IDCs will consume the precomputed default value,
  24098. * so we need to clone it.
  24099. */
  24100. if (iattr->val == NULL) {
  24101. VERROR_INT("xmlSchemaVAttributesComplex",
  24102. "default/fixed value on an attribute use was "
  24103. "not precomputed");
  24104. goto internal_error;
  24105. }
  24106. iattr->val = xmlSchemaCopyValue(iattr->val);
  24107. if (iattr->val == NULL) {
  24108. VERROR_INT("xmlSchemaVAttributesComplex",
  24109. "calling xmlSchemaCopyValue()");
  24110. goto internal_error;
  24111. }
  24112. }
  24113. /*
  24114. * PSVI: Add the default attribute to the current element.
  24115. * VAL TODO: Should we use the *normalized* value? This currently
  24116. * uses the *initial* value.
  24117. */
  24118. if (defAttrOwnerElem) {
  24119. xmlChar *normValue;
  24120. const xmlChar *value;
  24121. value = iattr->value;
  24122. /*
  24123. * Normalize the value.
  24124. */
  24125. normValue = xmlSchemaNormalizeValue(iattr->typeDef,
  24126. iattr->value);
  24127. if (normValue != NULL)
  24128. value = BAD_CAST normValue;
  24129. if (iattr->nsName == NULL) {
  24130. if (xmlNewProp(defAttrOwnerElem,
  24131. iattr->localName, value) == NULL) {
  24132. VERROR_INT("xmlSchemaVAttributesComplex",
  24133. "callling xmlNewProp()");
  24134. if (normValue != NULL)
  24135. xmlFree(normValue);
  24136. goto internal_error;
  24137. }
  24138. } else {
  24139. xmlNsPtr ns;
  24140. ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
  24141. defAttrOwnerElem, iattr->nsName);
  24142. if (ns == NULL) {
  24143. xmlChar prefix[12];
  24144. int counter = 0;
  24145. /*
  24146. * Create a namespace declaration on the validation
  24147. * root node if no namespace declaration is in scope.
  24148. */
  24149. do {
  24150. snprintf((char *) prefix, 12, "p%d", counter++);
  24151. ns = xmlSearchNs(defAttrOwnerElem->doc,
  24152. defAttrOwnerElem, BAD_CAST prefix);
  24153. if (counter > 1000) {
  24154. VERROR_INT(
  24155. "xmlSchemaVAttributesComplex",
  24156. "could not compute a ns prefix for a "
  24157. "default/fixed attribute");
  24158. if (normValue != NULL)
  24159. xmlFree(normValue);
  24160. goto internal_error;
  24161. }
  24162. } while (ns != NULL);
  24163. ns = xmlNewNs(vctxt->validationRoot,
  24164. iattr->nsName, BAD_CAST prefix);
  24165. }
  24166. /*
  24167. * TODO:
  24168. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
  24169. * If we have QNames: do we need to ensure there's a
  24170. * prefix defined for the QName?
  24171. */
  24172. xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
  24173. }
  24174. if (normValue != NULL)
  24175. xmlFree(normValue);
  24176. }
  24177. /*
  24178. * Go directly to IDC evaluation.
  24179. */
  24180. goto eval_idcs;
  24181. }
  24182. /*
  24183. * Validate the value.
  24184. */
  24185. if (vctxt->value != NULL) {
  24186. /*
  24187. * Free last computed value; just for safety reasons.
  24188. */
  24189. xmlSchemaFreeValue(vctxt->value);
  24190. vctxt->value = NULL;
  24191. }
  24192. /*
  24193. * Note that the attribute *use* can be unavailable, if
  24194. * the attribute was a wild attribute.
  24195. */
  24196. if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
  24197. ((iattr->use != NULL) &&
  24198. (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
  24199. fixed = 1;
  24200. else
  24201. fixed = 0;
  24202. /*
  24203. * SPEC (cvc-attribute)
  24204. * (3) "The item's �normalized value� must be locally �valid�
  24205. * with respect to that {type definition} as per
  24206. * String Valid (�3.14.4)."
  24207. *
  24208. * VAL TODO: Do we already have the
  24209. * "normalized attribute value" here?
  24210. */
  24211. if (xpathRes || fixed) {
  24212. iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  24213. /*
  24214. * Request a computed value.
  24215. */
  24216. res = xmlSchemaVCheckCVCSimpleType(
  24217. ACTXT_CAST vctxt,
  24218. iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
  24219. 1, 1, 0);
  24220. } else {
  24221. res = xmlSchemaVCheckCVCSimpleType(
  24222. ACTXT_CAST vctxt,
  24223. iattr->node, iattr->typeDef, iattr->value, NULL,
  24224. 1, 0, 0);
  24225. }
  24226. if (res != 0) {
  24227. if (res == -1) {
  24228. VERROR_INT("xmlSchemaVAttributesComplex",
  24229. "calling xmlSchemaStreamValidateSimpleTypeValue()");
  24230. goto internal_error;
  24231. }
  24232. iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
  24233. /*
  24234. * SPEC PSVI Assessment Outcome (Attribute)
  24235. * [validity] = "invalid"
  24236. */
  24237. goto eval_idcs;
  24238. }
  24239. if (fixed) {
  24240. /*
  24241. * SPEC Attribute Locally Valid (Use) (cvc-au)
  24242. * "For an attribute information item to be�valid�
  24243. * with respect to an attribute use its *normalized*
  24244. * value� must match the *canonical* lexical
  24245. * representation of the attribute use's {value
  24246. * constraint}value, if it is present and fixed."
  24247. *
  24248. * VAL TODO: The requirement for the *canonical* value
  24249. * will be removed in XML Schema 1.1.
  24250. */
  24251. /*
  24252. * SPEC Attribute Locally Valid (cvc-attribute)
  24253. * (4) "The item's *actual* value� must match the *value* of
  24254. * the {value constraint}, if it is present and fixed."
  24255. */
  24256. if (iattr->val == NULL) {
  24257. /* VAL TODO: A value was not precomputed. */
  24258. TODO
  24259. goto eval_idcs;
  24260. }
  24261. if ((iattr->use != NULL) &&
  24262. (iattr->use->defValue != NULL)) {
  24263. if (iattr->use->defVal == NULL) {
  24264. /* VAL TODO: A default value was not precomputed. */
  24265. TODO
  24266. goto eval_idcs;
  24267. }
  24268. iattr->vcValue = iattr->use->defValue;
  24269. /*
  24270. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24271. (xmlSchemaWhitespaceValueType) ws,
  24272. attr->use->defVal,
  24273. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24274. */
  24275. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
  24276. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24277. } else {
  24278. if (iattr->decl->defVal == NULL) {
  24279. /* VAL TODO: A default value was not precomputed. */
  24280. TODO
  24281. goto eval_idcs;
  24282. }
  24283. iattr->vcValue = iattr->decl->defValue;
  24284. /*
  24285. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24286. (xmlSchemaWhitespaceValueType) ws,
  24287. attrDecl->defVal,
  24288. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24289. */
  24290. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
  24291. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24292. }
  24293. /*
  24294. * [validity] = "valid"
  24295. */
  24296. }
  24297. eval_idcs:
  24298. /*
  24299. * Evaluate IDCs.
  24300. */
  24301. if (xpathRes) {
  24302. if (xmlSchemaXPathProcessHistory(vctxt,
  24303. vctxt->depth +1) == -1) {
  24304. VERROR_INT("xmlSchemaVAttributesComplex",
  24305. "calling xmlSchemaXPathEvaluate()");
  24306. goto internal_error;
  24307. }
  24308. } else if (vctxt->xpathStates != NULL)
  24309. xmlSchemaXPathPop(vctxt);
  24310. }
  24311. /*
  24312. * Report errors.
  24313. */
  24314. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24315. iattr = vctxt->attrInfos[i];
  24316. if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
  24317. (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
  24318. (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
  24319. (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
  24320. continue;
  24321. ACTIVATE_ATTRIBUTE(iattr);
  24322. switch (iattr->state) {
  24323. case XML_SCHEMAS_ATTR_ERR_MISSING: {
  24324. xmlChar *str = NULL;
  24325. ACTIVATE_ELEM;
  24326. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24327. XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
  24328. "The attribute '%s' is required but missing",
  24329. xmlSchemaFormatQName(&str,
  24330. iattr->decl->targetNamespace,
  24331. iattr->decl->name),
  24332. NULL);
  24333. FREE_AND_NULL(str)
  24334. break;
  24335. }
  24336. case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
  24337. VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
  24338. "The type definition is absent");
  24339. break;
  24340. case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
  24341. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24342. XML_SCHEMAV_CVC_AU, NULL, NULL,
  24343. "The value '%s' does not match the fixed "
  24344. "value constraint '%s'",
  24345. iattr->value, iattr->vcValue);
  24346. break;
  24347. case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
  24348. VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
  24349. "No matching global attribute declaration available, but "
  24350. "demanded by the strict wildcard");
  24351. break;
  24352. case XML_SCHEMAS_ATTR_UNKNOWN:
  24353. if (iattr->metaType)
  24354. break;
  24355. /*
  24356. * MAYBE VAL TODO: One might report different error messages
  24357. * for the following errors.
  24358. */
  24359. if (type->attributeWildcard == NULL) {
  24360. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24361. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
  24362. } else {
  24363. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24364. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
  24365. }
  24366. break;
  24367. default:
  24368. break;
  24369. }
  24370. }
  24371. ACTIVATE_ELEM;
  24372. return (0);
  24373. internal_error:
  24374. ACTIVATE_ELEM;
  24375. return (-1);
  24376. }
  24377. static int
  24378. xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
  24379. int *skip)
  24380. {
  24381. xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
  24382. /*
  24383. * The namespace of the element was already identified to be
  24384. * matching the wildcard.
  24385. */
  24386. if ((skip == NULL) || (wild == NULL) ||
  24387. (wild->type != XML_SCHEMA_TYPE_ANY)) {
  24388. VERROR_INT("xmlSchemaValidateElemWildcard",
  24389. "bad arguments");
  24390. return (-1);
  24391. }
  24392. *skip = 0;
  24393. if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
  24394. /*
  24395. * URGENT VAL TODO: Either we need to position the stream to the
  24396. * next sibling, or walk the whole subtree.
  24397. */
  24398. *skip = 1;
  24399. return (0);
  24400. }
  24401. {
  24402. xmlSchemaElementPtr decl = NULL;
  24403. decl = xmlSchemaGetElem(vctxt->schema,
  24404. vctxt->inode->localName, vctxt->inode->nsName);
  24405. if (decl != NULL) {
  24406. vctxt->inode->decl = decl;
  24407. return (0);
  24408. }
  24409. }
  24410. if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
  24411. /* VAL TODO: Change to proper error code. */
  24412. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
  24413. "No matching global element declaration available, but "
  24414. "demanded by the strict wildcard");
  24415. return (vctxt->err);
  24416. }
  24417. if (vctxt->nbAttrInfos != 0) {
  24418. xmlSchemaAttrInfoPtr iattr;
  24419. /*
  24420. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24421. * (1.2.1.2.1) - (1.2.1.2.3 )
  24422. *
  24423. * Use the xsi:type attribute for the type definition.
  24424. */
  24425. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  24426. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  24427. if (iattr != NULL) {
  24428. if (xmlSchemaProcessXSIType(vctxt, iattr,
  24429. &(vctxt->inode->typeDef), NULL) == -1) {
  24430. VERROR_INT("xmlSchemaValidateElemWildcard",
  24431. "calling xmlSchemaProcessXSIType() to "
  24432. "process the attribute 'xsi:nil'");
  24433. return (-1);
  24434. }
  24435. /*
  24436. * Don't return an error on purpose.
  24437. */
  24438. return (0);
  24439. }
  24440. }
  24441. /*
  24442. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24443. *
  24444. * Fallback to "anyType".
  24445. */
  24446. vctxt->inode->typeDef =
  24447. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  24448. return (0);
  24449. }
  24450. /*
  24451. * xmlSchemaCheckCOSValidDefault:
  24452. *
  24453. * This will be called if: not nilled, no content and a default/fixed
  24454. * value is provided.
  24455. */
  24456. static int
  24457. xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
  24458. const xmlChar *value,
  24459. xmlSchemaValPtr *val)
  24460. {
  24461. int ret = 0;
  24462. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24463. /*
  24464. * cos-valid-default:
  24465. * Schema Component Constraint: Element Default Valid (Immediate)
  24466. * For a string to be a valid default with respect to a type
  24467. * definition the appropriate case among the following must be true:
  24468. */
  24469. if WXS_IS_COMPLEX(inode->typeDef) {
  24470. /*
  24471. * Complex type.
  24472. *
  24473. * SPEC (2.1) "its {content type} must be a simple type definition
  24474. * or mixed."
  24475. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  24476. * type}'s particle must be �emptiable� as defined by
  24477. * Particle Emptiable (�3.9.6)."
  24478. */
  24479. if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
  24480. ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
  24481. (! WXS_EMPTIABLE(inode->typeDef)))) {
  24482. ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
  24483. /* NOTE that this covers (2.2.2) as well. */
  24484. VERROR(ret, NULL,
  24485. "For a string to be a valid default, the type definition "
  24486. "must be a simple type or a complex type with simple content "
  24487. "or mixed content and a particle emptiable");
  24488. return(ret);
  24489. }
  24490. }
  24491. /*
  24492. * 1 If the type definition is a simple type definition, then the string
  24493. * must be �valid� with respect to that definition as defined by String
  24494. * Valid (�3.14.4).
  24495. *
  24496. * AND
  24497. *
  24498. * 2.2.1 If the {content type} is a simple type definition, then the
  24499. * string must be �valid� with respect to that simple type definition
  24500. * as defined by String Valid (�3.14.4).
  24501. */
  24502. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24503. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24504. NULL, inode->typeDef, value, val, 1, 1, 0);
  24505. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24506. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24507. NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
  24508. }
  24509. if (ret < 0) {
  24510. VERROR_INT("xmlSchemaCheckCOSValidDefault",
  24511. "calling xmlSchemaVCheckCVCSimpleType()");
  24512. }
  24513. return (ret);
  24514. }
  24515. static void
  24516. xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  24517. const xmlChar * name ATTRIBUTE_UNUSED,
  24518. xmlSchemaElementPtr item,
  24519. xmlSchemaNodeInfoPtr inode)
  24520. {
  24521. inode->decl = item;
  24522. #ifdef DEBUG_CONTENT
  24523. {
  24524. xmlChar *str = NULL;
  24525. if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
  24526. xmlGenericError(xmlGenericErrorContext,
  24527. "AUTOMATON callback for '%s' [declaration]\n",
  24528. xmlSchemaFormatQName(&str,
  24529. inode->localName, inode->nsName));
  24530. } else {
  24531. xmlGenericError(xmlGenericErrorContext,
  24532. "AUTOMATON callback for '%s' [wildcard]\n",
  24533. xmlSchemaFormatQName(&str,
  24534. inode->localName, inode->nsName));
  24535. }
  24536. FREE_AND_NULL(str)
  24537. }
  24538. #endif
  24539. }
  24540. static int
  24541. xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
  24542. {
  24543. vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
  24544. if (vctxt->inode == NULL) {
  24545. VERROR_INT("xmlSchemaValidatorPushElem",
  24546. "calling xmlSchemaGetFreshElemInfo()");
  24547. return (-1);
  24548. }
  24549. vctxt->nbAttrInfos = 0;
  24550. return (0);
  24551. }
  24552. static int
  24553. xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
  24554. xmlSchemaNodeInfoPtr inode,
  24555. xmlSchemaTypePtr type,
  24556. const xmlChar *value)
  24557. {
  24558. if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
  24559. return (xmlSchemaVCheckCVCSimpleType(
  24560. ACTXT_CAST vctxt, NULL,
  24561. type, value, &(inode->val), 1, 1, 0));
  24562. else
  24563. return (xmlSchemaVCheckCVCSimpleType(
  24564. ACTXT_CAST vctxt, NULL,
  24565. type, value, NULL, 1, 0, 0));
  24566. }
  24567. /*
  24568. * Process END of element.
  24569. */
  24570. static int
  24571. xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
  24572. {
  24573. int ret = 0;
  24574. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24575. if (vctxt->nbAttrInfos != 0)
  24576. xmlSchemaClearAttrInfos(vctxt);
  24577. if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
  24578. /*
  24579. * This element was not expected;
  24580. * we will not validate child elements of broken parents.
  24581. * Skip validation of all content of the parent.
  24582. */
  24583. vctxt->skipDepth = vctxt->depth -1;
  24584. goto end_elem;
  24585. }
  24586. if ((inode->typeDef == NULL) ||
  24587. (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
  24588. /*
  24589. * 1. the type definition might be missing if the element was
  24590. * error prone
  24591. * 2. it might be abstract.
  24592. */
  24593. goto end_elem;
  24594. }
  24595. /*
  24596. * Check the content model.
  24597. */
  24598. if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
  24599. (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
  24600. /*
  24601. * Workaround for "anyType".
  24602. */
  24603. if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
  24604. goto character_content;
  24605. if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
  24606. xmlChar *values[10];
  24607. int terminal, nbval = 10, nbneg;
  24608. if (inode->regexCtxt == NULL) {
  24609. /*
  24610. * Create the regex context.
  24611. */
  24612. inode->regexCtxt =
  24613. xmlRegNewExecCtxt(inode->typeDef->contModel,
  24614. (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
  24615. vctxt);
  24616. if (inode->regexCtxt == NULL) {
  24617. VERROR_INT("xmlSchemaValidatorPopElem",
  24618. "failed to create a regex context");
  24619. goto internal_error;
  24620. }
  24621. #ifdef DEBUG_AUTOMATA
  24622. xmlGenericError(xmlGenericErrorContext,
  24623. "AUTOMATON create on '%s'\n", inode->localName);
  24624. #endif
  24625. }
  24626. /*
  24627. * Get hold of the still expected content, since a further
  24628. * call to xmlRegExecPushString() will loose this information.
  24629. */
  24630. xmlRegExecNextValues(inode->regexCtxt,
  24631. &nbval, &nbneg, &values[0], &terminal);
  24632. ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
  24633. if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
  24634. /*
  24635. * Still missing something.
  24636. */
  24637. ret = 1;
  24638. inode->flags |=
  24639. XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  24640. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  24641. XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
  24642. "Missing child element(s)",
  24643. nbval, nbneg, values);
  24644. #ifdef DEBUG_AUTOMATA
  24645. xmlGenericError(xmlGenericErrorContext,
  24646. "AUTOMATON missing ERROR on '%s'\n",
  24647. inode->localName);
  24648. #endif
  24649. } else {
  24650. /*
  24651. * Content model is satisfied.
  24652. */
  24653. ret = 0;
  24654. #ifdef DEBUG_AUTOMATA
  24655. xmlGenericError(xmlGenericErrorContext,
  24656. "AUTOMATON succeeded on '%s'\n",
  24657. inode->localName);
  24658. #endif
  24659. }
  24660. }
  24661. }
  24662. if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
  24663. goto end_elem;
  24664. character_content:
  24665. if (vctxt->value != NULL) {
  24666. xmlSchemaFreeValue(vctxt->value);
  24667. vctxt->value = NULL;
  24668. }
  24669. /*
  24670. * Check character content.
  24671. */
  24672. if (inode->decl == NULL) {
  24673. /*
  24674. * Speedup if no declaration exists.
  24675. */
  24676. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24677. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24678. inode, inode->typeDef, inode->value);
  24679. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24680. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24681. inode, inode->typeDef->contentTypeDef,
  24682. inode->value);
  24683. }
  24684. if (ret < 0) {
  24685. VERROR_INT("xmlSchemaValidatorPopElem",
  24686. "calling xmlSchemaVCheckCVCSimpleType()");
  24687. goto internal_error;
  24688. }
  24689. goto end_elem;
  24690. }
  24691. /*
  24692. * cvc-elt (3.3.4) : 5
  24693. * The appropriate case among the following must be true:
  24694. */
  24695. /*
  24696. * cvc-elt (3.3.4) : 5.1
  24697. * If the declaration has a {value constraint},
  24698. * the item has neither element nor character [children] and
  24699. * clause 3.2 has not applied, then all of the following must be true:
  24700. */
  24701. if ((inode->decl->value != NULL) &&
  24702. (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
  24703. (! INODE_NILLED(inode))) {
  24704. /*
  24705. * cvc-elt (3.3.4) : 5.1.1
  24706. * If the �actual type definition� is a �local type definition�
  24707. * then the canonical lexical representation of the {value constraint}
  24708. * value must be a valid default for the �actual type definition� as
  24709. * defined in Element Default Valid (Immediate) (�3.3.6).
  24710. */
  24711. /*
  24712. * NOTE: 'local' above means types acquired by xsi:type.
  24713. * NOTE: Although the *canonical* value is stated, it is not
  24714. * relevant if canonical or not. Additionally XML Schema 1.1
  24715. * will removed this requirement as well.
  24716. */
  24717. if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
  24718. ret = xmlSchemaCheckCOSValidDefault(vctxt,
  24719. inode->decl->value, &(inode->val));
  24720. if (ret != 0) {
  24721. if (ret < 0) {
  24722. VERROR_INT("xmlSchemaValidatorPopElem",
  24723. "calling xmlSchemaCheckCOSValidDefault()");
  24724. goto internal_error;
  24725. }
  24726. goto end_elem;
  24727. }
  24728. /*
  24729. * Stop here, to avoid redundant validation of the value
  24730. * (see following).
  24731. */
  24732. goto default_psvi;
  24733. }
  24734. /*
  24735. * cvc-elt (3.3.4) : 5.1.2
  24736. * The element information item with the canonical lexical
  24737. * representation of the {value constraint} value used as its
  24738. * �normalized value� must be �valid� with respect to the
  24739. * �actual type definition� as defined by Element Locally Valid (Type)
  24740. * (�3.3.4).
  24741. */
  24742. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24743. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24744. inode, inode->typeDef, inode->decl->value);
  24745. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24746. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24747. inode, inode->typeDef->contentTypeDef,
  24748. inode->decl->value);
  24749. }
  24750. if (ret != 0) {
  24751. if (ret < 0) {
  24752. VERROR_INT("xmlSchemaValidatorPopElem",
  24753. "calling xmlSchemaVCheckCVCSimpleType()");
  24754. goto internal_error;
  24755. }
  24756. goto end_elem;
  24757. }
  24758. default_psvi:
  24759. /*
  24760. * PSVI: Create a text node on the instance element.
  24761. */
  24762. if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
  24763. (inode->node != NULL)) {
  24764. xmlNodePtr textChild;
  24765. xmlChar *normValue;
  24766. /*
  24767. * VAL TODO: Normalize the value.
  24768. */
  24769. normValue = xmlSchemaNormalizeValue(inode->typeDef,
  24770. inode->decl->value);
  24771. if (normValue != NULL) {
  24772. textChild = xmlNewText(BAD_CAST normValue);
  24773. xmlFree(normValue);
  24774. } else
  24775. textChild = xmlNewText(inode->decl->value);
  24776. if (textChild == NULL) {
  24777. VERROR_INT("xmlSchemaValidatorPopElem",
  24778. "calling xmlNewText()");
  24779. goto internal_error;
  24780. } else
  24781. xmlAddChild(inode->node, textChild);
  24782. }
  24783. } else if (! INODE_NILLED(inode)) {
  24784. /*
  24785. * 5.2.1 The element information item must be �valid� with respect
  24786. * to the �actual type definition� as defined by Element Locally
  24787. * Valid (Type) (�3.3.4).
  24788. */
  24789. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24790. /*
  24791. * SPEC (cvc-type) (3.1)
  24792. * "If the type definition is a simple type definition, ..."
  24793. * (3.1.3) "If clause 3.2 of Element Locally Valid
  24794. * (Element) (�3.3.4) did not apply, then the �normalized value�
  24795. * must be �valid� with respect to the type definition as defined
  24796. * by String Valid (�3.14.4).
  24797. */
  24798. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24799. inode, inode->typeDef, inode->value);
  24800. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24801. /*
  24802. * SPEC (cvc-type) (3.2) "If the type definition is a complex type
  24803. * definition, then the element information item must be
  24804. * �valid� with respect to the type definition as per
  24805. * Element Locally Valid (Complex Type) (�3.4.4);"
  24806. *
  24807. * SPEC (cvc-complex-type) (2.2)
  24808. * "If the {content type} is a simple type definition, ...
  24809. * the �normalized value� of the element information item is
  24810. * �valid� with respect to that simple type definition as
  24811. * defined by String Valid (�3.14.4)."
  24812. */
  24813. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24814. inode, inode->typeDef->contentTypeDef, inode->value);
  24815. }
  24816. if (ret != 0) {
  24817. if (ret < 0) {
  24818. VERROR_INT("xmlSchemaValidatorPopElem",
  24819. "calling xmlSchemaVCheckCVCSimpleType()");
  24820. goto internal_error;
  24821. }
  24822. goto end_elem;
  24823. }
  24824. /*
  24825. * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
  24826. * not applied, all of the following must be true:
  24827. */
  24828. if ((inode->decl->value != NULL) &&
  24829. (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
  24830. /*
  24831. * TODO: We will need a computed value, when comparison is
  24832. * done on computed values.
  24833. */
  24834. /*
  24835. * 5.2.2.1 The element information item must have no element
  24836. * information item [children].
  24837. */
  24838. if (inode->flags &
  24839. XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
  24840. ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
  24841. VERROR(ret, NULL,
  24842. "The content must not containt element nodes since "
  24843. "there is a fixed value constraint");
  24844. goto end_elem;
  24845. } else {
  24846. /*
  24847. * 5.2.2.2 The appropriate case among the following must
  24848. * be true:
  24849. */
  24850. if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
  24851. /*
  24852. * 5.2.2.2.1 If the {content type} of the �actual type
  24853. * definition� is mixed, then the *initial value* of the
  24854. * item must match the canonical lexical representation
  24855. * of the {value constraint} value.
  24856. *
  24857. * ... the *initial value* of an element information
  24858. * item is the string composed of, in order, the
  24859. * [character code] of each character information item in
  24860. * the [children] of that element information item.
  24861. */
  24862. if (! xmlStrEqual(inode->value, inode->decl->value)){
  24863. /*
  24864. * VAL TODO: Report invalid & expected values as well.
  24865. * VAL TODO: Implement the canonical stuff.
  24866. */
  24867. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
  24868. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24869. ret, NULL, NULL,
  24870. "The initial value '%s' does not match the fixed "
  24871. "value constraint '%s'",
  24872. inode->value, inode->decl->value);
  24873. goto end_elem;
  24874. }
  24875. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24876. /*
  24877. * 5.2.2.2.2 If the {content type} of the �actual type
  24878. * definition� is a simple type definition, then the
  24879. * *actual value* of the item must match the canonical
  24880. * lexical representation of the {value constraint} value.
  24881. */
  24882. /*
  24883. * VAL TODO: *actual value* is the normalized value, impl.
  24884. * this.
  24885. * VAL TODO: Report invalid & expected values as well.
  24886. * VAL TODO: Implement a comparison with the computed values.
  24887. */
  24888. if (! xmlStrEqual(inode->value,
  24889. inode->decl->value)) {
  24890. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
  24891. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24892. ret, NULL, NULL,
  24893. "The actual value '%s' does not match the fixed "
  24894. "value constraint '%s'",
  24895. inode->value,
  24896. inode->decl->value);
  24897. goto end_elem;
  24898. }
  24899. }
  24900. }
  24901. }
  24902. }
  24903. end_elem:
  24904. if (vctxt->depth < 0) {
  24905. /* TODO: raise error? */
  24906. return (0);
  24907. }
  24908. if (vctxt->depth == vctxt->skipDepth)
  24909. vctxt->skipDepth = -1;
  24910. /*
  24911. * Evaluate the history of XPath state objects.
  24912. */
  24913. if (inode->appliedXPath &&
  24914. (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
  24915. goto internal_error;
  24916. /*
  24917. * MAYBE TODO:
  24918. * SPEC (6) "The element information item must be �valid� with
  24919. * respect to each of the {identity-constraint definitions} as per
  24920. * Identity-constraint Satisfied (�3.11.4)."
  24921. */
  24922. /*
  24923. * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
  24924. * need to be built in any case.
  24925. * We will currently build IDC node-tables and bubble them only if
  24926. * keyrefs do exist.
  24927. */
  24928. /*
  24929. * Add the current IDC target-nodes to the IDC node-tables.
  24930. */
  24931. if ((inode->idcMatchers != NULL) &&
  24932. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  24933. {
  24934. if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
  24935. goto internal_error;
  24936. }
  24937. /*
  24938. * Validate IDC keyrefs.
  24939. */
  24940. if (vctxt->inode->hasKeyrefs)
  24941. if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
  24942. goto internal_error;
  24943. /*
  24944. * Merge/free the IDC table.
  24945. */
  24946. if (inode->idcTable != NULL) {
  24947. #ifdef DEBUG_IDC_NODE_TABLE
  24948. xmlSchemaDebugDumpIDCTable(stdout,
  24949. inode->nsName,
  24950. inode->localName,
  24951. inode->idcTable);
  24952. #endif
  24953. if ((vctxt->depth > 0) &&
  24954. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  24955. {
  24956. /*
  24957. * Merge the IDC node table with the table of the parent node.
  24958. */
  24959. if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
  24960. goto internal_error;
  24961. }
  24962. }
  24963. /*
  24964. * Clear the current ielem.
  24965. * VAL TODO: Don't free the PSVI IDC tables if they are
  24966. * requested for the PSVI.
  24967. */
  24968. xmlSchemaClearElemInfo(vctxt, inode);
  24969. /*
  24970. * Skip further processing if we are on the validation root.
  24971. */
  24972. if (vctxt->depth == 0) {
  24973. vctxt->depth--;
  24974. vctxt->inode = NULL;
  24975. return (0);
  24976. }
  24977. /*
  24978. * Reset the keyrefDepth if needed.
  24979. */
  24980. if (vctxt->aidcs != NULL) {
  24981. xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
  24982. do {
  24983. if (aidc->keyrefDepth == vctxt->depth) {
  24984. /*
  24985. * A 'keyrefDepth' of a key/unique IDC matches the current
  24986. * depth, this means that we are leaving the scope of the
  24987. * top-most keyref IDC which refers to this IDC.
  24988. */
  24989. aidc->keyrefDepth = -1;
  24990. }
  24991. aidc = aidc->next;
  24992. } while (aidc != NULL);
  24993. }
  24994. vctxt->depth--;
  24995. vctxt->inode = vctxt->elemInfos[vctxt->depth];
  24996. /*
  24997. * VAL TODO: 7 If the element information item is the �validation root�, it must be
  24998. * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
  24999. */
  25000. return (ret);
  25001. internal_error:
  25002. vctxt->err = -1;
  25003. return (-1);
  25004. }
  25005. /*
  25006. * 3.4.4 Complex Type Definition Validation Rules
  25007. * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
  25008. */
  25009. static int
  25010. xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
  25011. {
  25012. xmlSchemaNodeInfoPtr pielem;
  25013. xmlSchemaTypePtr ptype;
  25014. int ret = 0;
  25015. if (vctxt->depth <= 0) {
  25016. VERROR_INT("xmlSchemaValidateChildElem",
  25017. "not intended for the validation root");
  25018. return (-1);
  25019. }
  25020. pielem = vctxt->elemInfos[vctxt->depth -1];
  25021. if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25022. pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25023. /*
  25024. * Handle 'nilled' elements.
  25025. */
  25026. if (INODE_NILLED(pielem)) {
  25027. /*
  25028. * SPEC (cvc-elt) (3.3.4) : (3.2.1)
  25029. */
  25030. ACTIVATE_PARENT_ELEM;
  25031. ret = XML_SCHEMAV_CVC_ELT_3_2_1;
  25032. VERROR(ret, NULL,
  25033. "Neither character nor element content is allowed, "
  25034. "because the element was 'nilled'");
  25035. ACTIVATE_ELEM;
  25036. goto unexpected_elem;
  25037. }
  25038. ptype = pielem->typeDef;
  25039. if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
  25040. /*
  25041. * Workaround for "anyType": we have currently no content model
  25042. * assigned for "anyType", so handle it explicitely.
  25043. * "anyType" has an unbounded, lax "any" wildcard.
  25044. */
  25045. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25046. vctxt->inode->localName,
  25047. vctxt->inode->nsName);
  25048. if (vctxt->inode->decl == NULL) {
  25049. xmlSchemaAttrInfoPtr iattr;
  25050. /*
  25051. * Process "xsi:type".
  25052. * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
  25053. */
  25054. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  25055. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  25056. if (iattr != NULL) {
  25057. ret = xmlSchemaProcessXSIType(vctxt, iattr,
  25058. &(vctxt->inode->typeDef), NULL);
  25059. if (ret != 0) {
  25060. if (ret == -1) {
  25061. VERROR_INT("xmlSchemaValidateChildElem",
  25062. "calling xmlSchemaProcessXSIType() to "
  25063. "process the attribute 'xsi:nil'");
  25064. return (-1);
  25065. }
  25066. return (ret);
  25067. }
  25068. } else {
  25069. /*
  25070. * Fallback to "anyType".
  25071. *
  25072. * SPEC (cvc-assess-elt)
  25073. * "If the item cannot be �strictly assessed�, [...]
  25074. * an element information item's schema validity may be laxly
  25075. * assessed if its �context-determined declaration� is not
  25076. * skip by �validating� with respect to the �ur-type
  25077. * definition� as per Element Locally Valid (Type) (�3.3.4)."
  25078. */
  25079. vctxt->inode->typeDef =
  25080. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  25081. }
  25082. }
  25083. return (0);
  25084. }
  25085. switch (ptype->contentType) {
  25086. case XML_SCHEMA_CONTENT_EMPTY:
  25087. /*
  25088. * SPEC (2.1) "If the {content type} is empty, then the
  25089. * element information item has no character or element
  25090. * information item [children]."
  25091. */
  25092. ACTIVATE_PARENT_ELEM
  25093. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
  25094. VERROR(ret, NULL,
  25095. "Element content is not allowed, "
  25096. "because the content type is empty");
  25097. ACTIVATE_ELEM
  25098. goto unexpected_elem;
  25099. break;
  25100. case XML_SCHEMA_CONTENT_MIXED:
  25101. case XML_SCHEMA_CONTENT_ELEMENTS: {
  25102. xmlRegExecCtxtPtr regexCtxt;
  25103. xmlChar *values[10];
  25104. int terminal, nbval = 10, nbneg;
  25105. /* VAL TODO: Optimized "anyType" validation.*/
  25106. if (ptype->contModel == NULL) {
  25107. VERROR_INT("xmlSchemaValidateChildElem",
  25108. "type has elem content but no content model");
  25109. return (-1);
  25110. }
  25111. /*
  25112. * Safety belf for evaluation if the cont. model was already
  25113. * examined to be invalid.
  25114. */
  25115. if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
  25116. VERROR_INT("xmlSchemaValidateChildElem",
  25117. "validating elem, but elem content is already invalid");
  25118. return (-1);
  25119. }
  25120. regexCtxt = pielem->regexCtxt;
  25121. if (regexCtxt == NULL) {
  25122. /*
  25123. * Create the regex context.
  25124. */
  25125. regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
  25126. (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
  25127. vctxt);
  25128. if (regexCtxt == NULL) {
  25129. VERROR_INT("xmlSchemaValidateChildElem",
  25130. "failed to create a regex context");
  25131. return (-1);
  25132. }
  25133. pielem->regexCtxt = regexCtxt;
  25134. #ifdef DEBUG_AUTOMATA
  25135. xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
  25136. pielem->localName);
  25137. #endif
  25138. }
  25139. /*
  25140. * SPEC (2.4) "If the {content type} is element-only or mixed,
  25141. * then the sequence of the element information item's
  25142. * element information item [children], if any, taken in
  25143. * order, is �valid� with respect to the {content type}'s
  25144. * particle, as defined in Element Sequence Locally Valid
  25145. * (Particle) (�3.9.4)."
  25146. */
  25147. ret = xmlRegExecPushString2(regexCtxt,
  25148. vctxt->inode->localName,
  25149. vctxt->inode->nsName,
  25150. vctxt->inode);
  25151. #ifdef DEBUG_AUTOMATA
  25152. if (ret < 0)
  25153. xmlGenericError(xmlGenericErrorContext,
  25154. "AUTOMATON push ERROR for '%s' on '%s'\n",
  25155. vctxt->inode->localName, pielem->localName);
  25156. else
  25157. xmlGenericError(xmlGenericErrorContext,
  25158. "AUTOMATON push OK for '%s' on '%s'\n",
  25159. vctxt->inode->localName, pielem->localName);
  25160. #endif
  25161. if (vctxt->err == XML_SCHEMAV_INTERNAL) {
  25162. VERROR_INT("xmlSchemaValidateChildElem",
  25163. "calling xmlRegExecPushString2()");
  25164. return (-1);
  25165. }
  25166. if (ret < 0) {
  25167. xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
  25168. &values[0], &terminal);
  25169. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  25170. XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
  25171. "This element is not expected",
  25172. nbval, nbneg, values);
  25173. ret = vctxt->err;
  25174. goto unexpected_elem;
  25175. } else
  25176. ret = 0;
  25177. }
  25178. break;
  25179. case XML_SCHEMA_CONTENT_SIMPLE:
  25180. case XML_SCHEMA_CONTENT_BASIC:
  25181. ACTIVATE_PARENT_ELEM
  25182. if (WXS_IS_COMPLEX(ptype)) {
  25183. /*
  25184. * SPEC (cvc-complex-type) (2.2)
  25185. * "If the {content type} is a simple type definition, then
  25186. * the element information item has no element information
  25187. * item [children], ..."
  25188. */
  25189. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
  25190. VERROR(ret, NULL, "Element content is not allowed, "
  25191. "because the content type is a simple type definition");
  25192. } else {
  25193. /*
  25194. * SPEC (cvc-type) (3.1.2) "The element information item must
  25195. * have no element information item [children]."
  25196. */
  25197. ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
  25198. VERROR(ret, NULL, "Element content is not allowed, "
  25199. "because the type definition is simple");
  25200. }
  25201. ACTIVATE_ELEM
  25202. ret = vctxt->err;
  25203. goto unexpected_elem;
  25204. break;
  25205. default:
  25206. break;
  25207. }
  25208. return (ret);
  25209. unexpected_elem:
  25210. /*
  25211. * Pop this element and set the skipDepth to skip
  25212. * all further content of the parent element.
  25213. */
  25214. vctxt->skipDepth = vctxt->depth;
  25215. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
  25216. pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  25217. return (ret);
  25218. }
  25219. #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
  25220. #define XML_SCHEMA_PUSH_TEXT_CREATED 2
  25221. #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
  25222. static int
  25223. xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
  25224. int nodeType, const xmlChar *value, int len,
  25225. int mode, int *consumed)
  25226. {
  25227. /*
  25228. * Unfortunately we have to duplicate the text sometimes.
  25229. * OPTIMIZE: Maybe we could skip it, if:
  25230. * 1. content type is simple
  25231. * 2. whitespace is "collapse"
  25232. * 3. it consists of whitespace only
  25233. *
  25234. * Process character content.
  25235. */
  25236. if (consumed != NULL)
  25237. *consumed = 0;
  25238. if (INODE_NILLED(vctxt->inode)) {
  25239. /*
  25240. * SPEC cvc-elt (3.3.4 - 3.2.1)
  25241. * "The element information item must have no character or
  25242. * element information item [children]."
  25243. */
  25244. VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
  25245. "Neither character nor element content is allowed "
  25246. "because the element is 'nilled'");
  25247. return (vctxt->err);
  25248. }
  25249. /*
  25250. * SPEC (2.1) "If the {content type} is empty, then the
  25251. * element information item has no character or element
  25252. * information item [children]."
  25253. */
  25254. if (vctxt->inode->typeDef->contentType ==
  25255. XML_SCHEMA_CONTENT_EMPTY) {
  25256. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
  25257. "Character content is not allowed, "
  25258. "because the content type is empty");
  25259. return (vctxt->err);
  25260. }
  25261. if (vctxt->inode->typeDef->contentType ==
  25262. XML_SCHEMA_CONTENT_ELEMENTS) {
  25263. if ((nodeType != XML_TEXT_NODE) ||
  25264. (! xmlSchemaIsBlank((xmlChar *) value, len))) {
  25265. /*
  25266. * SPEC cvc-complex-type (2.3)
  25267. * "If the {content type} is element-only, then the
  25268. * element information item has no character information
  25269. * item [children] other than those whose [character
  25270. * code] is defined as a white space in [XML 1.0 (Second
  25271. * Edition)]."
  25272. */
  25273. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
  25274. "Character content other than whitespace is not allowed "
  25275. "because the content type is 'element-only'");
  25276. return (vctxt->err);
  25277. }
  25278. return (0);
  25279. }
  25280. if ((value == NULL) || (value[0] == 0))
  25281. return (0);
  25282. /*
  25283. * Save the value.
  25284. * NOTE that even if the content type is *mixed*, we need the
  25285. * *initial value* for default/fixed value constraints.
  25286. */
  25287. if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  25288. ((vctxt->inode->decl == NULL) ||
  25289. (vctxt->inode->decl->value == NULL)))
  25290. return (0);
  25291. if (vctxt->inode->value == NULL) {
  25292. /*
  25293. * Set the value.
  25294. */
  25295. switch (mode) {
  25296. case XML_SCHEMA_PUSH_TEXT_PERSIST:
  25297. /*
  25298. * When working on a tree.
  25299. */
  25300. vctxt->inode->value = value;
  25301. break;
  25302. case XML_SCHEMA_PUSH_TEXT_CREATED:
  25303. /*
  25304. * When working with the reader.
  25305. * The value will be freed by the element info.
  25306. */
  25307. vctxt->inode->value = value;
  25308. if (consumed != NULL)
  25309. *consumed = 1;
  25310. vctxt->inode->flags |=
  25311. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25312. break;
  25313. case XML_SCHEMA_PUSH_TEXT_VOLATILE:
  25314. /*
  25315. * When working with SAX.
  25316. * The value will be freed by the element info.
  25317. */
  25318. if (len != -1)
  25319. vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
  25320. else
  25321. vctxt->inode->value = BAD_CAST xmlStrdup(value);
  25322. vctxt->inode->flags |=
  25323. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25324. break;
  25325. default:
  25326. break;
  25327. }
  25328. } else {
  25329. if (len < 0)
  25330. len = xmlStrlen(value);
  25331. /*
  25332. * Concat the value.
  25333. */
  25334. if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  25335. vctxt->inode->value = BAD_CAST xmlStrncat(
  25336. (xmlChar *) vctxt->inode->value, value, len);
  25337. } else {
  25338. vctxt->inode->value =
  25339. BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
  25340. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25341. }
  25342. }
  25343. return (0);
  25344. }
  25345. static int
  25346. xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
  25347. {
  25348. int ret = 0;
  25349. if ((vctxt->skipDepth != -1) &&
  25350. (vctxt->depth >= vctxt->skipDepth)) {
  25351. VERROR_INT("xmlSchemaValidateElem",
  25352. "in skip-state");
  25353. goto internal_error;
  25354. }
  25355. if (vctxt->xsiAssemble) {
  25356. /*
  25357. * We will stop validation if there was an error during
  25358. * dynamic schema construction.
  25359. * Note that we simply set @skipDepth to 0, this could
  25360. * mean that a streaming document via SAX would be
  25361. * still read to the end but it won't be validated any more.
  25362. * TODO: If we are sure how to stop the validation at once
  25363. * for all input scenarios, then this should be changed to
  25364. * instantly stop the validation.
  25365. */
  25366. ret = xmlSchemaAssembleByXSI(vctxt);
  25367. if (ret != 0) {
  25368. if (ret == -1)
  25369. goto internal_error;
  25370. vctxt->skipDepth = 0;
  25371. return(ret);
  25372. }
  25373. }
  25374. if (vctxt->depth > 0) {
  25375. /*
  25376. * Validate this element against the content model
  25377. * of the parent.
  25378. */
  25379. ret = xmlSchemaValidateChildElem(vctxt);
  25380. if (ret != 0) {
  25381. if (ret < 0) {
  25382. VERROR_INT("xmlSchemaValidateElem",
  25383. "calling xmlSchemaStreamValidateChildElement()");
  25384. goto internal_error;
  25385. }
  25386. goto exit;
  25387. }
  25388. if (vctxt->depth == vctxt->skipDepth)
  25389. goto exit;
  25390. if ((vctxt->inode->decl == NULL) &&
  25391. (vctxt->inode->typeDef == NULL)) {
  25392. VERROR_INT("xmlSchemaValidateElem",
  25393. "the child element was valid but neither the "
  25394. "declaration nor the type was set");
  25395. goto internal_error;
  25396. }
  25397. } else {
  25398. /*
  25399. * Get the declaration of the validation root.
  25400. */
  25401. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25402. vctxt->inode->localName,
  25403. vctxt->inode->nsName);
  25404. if (vctxt->inode->decl == NULL) {
  25405. ret = XML_SCHEMAV_CVC_ELT_1;
  25406. VERROR(ret, NULL,
  25407. "No matching global declaration available "
  25408. "for the validation root");
  25409. goto exit;
  25410. }
  25411. }
  25412. if (vctxt->inode->decl == NULL)
  25413. goto type_validation;
  25414. if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
  25415. int skip;
  25416. /*
  25417. * Wildcards.
  25418. */
  25419. ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
  25420. if (ret != 0) {
  25421. if (ret < 0) {
  25422. VERROR_INT("xmlSchemaValidateElem",
  25423. "calling xmlSchemaValidateElemWildcard()");
  25424. goto internal_error;
  25425. }
  25426. goto exit;
  25427. }
  25428. if (skip) {
  25429. vctxt->skipDepth = vctxt->depth;
  25430. goto exit;
  25431. }
  25432. /*
  25433. * The declaration might be set by the wildcard validation,
  25434. * when the processContents is "lax" or "strict".
  25435. */
  25436. if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
  25437. /*
  25438. * Clear the "decl" field to not confuse further processing.
  25439. */
  25440. vctxt->inode->decl = NULL;
  25441. goto type_validation;
  25442. }
  25443. }
  25444. /*
  25445. * Validate against the declaration.
  25446. */
  25447. ret = xmlSchemaValidateElemDecl(vctxt);
  25448. if (ret != 0) {
  25449. if (ret < 0) {
  25450. VERROR_INT("xmlSchemaValidateElem",
  25451. "calling xmlSchemaValidateElemDecl()");
  25452. goto internal_error;
  25453. }
  25454. goto exit;
  25455. }
  25456. /*
  25457. * Validate against the type definition.
  25458. */
  25459. type_validation:
  25460. if (vctxt->inode->typeDef == NULL) {
  25461. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25462. ret = XML_SCHEMAV_CVC_TYPE_1;
  25463. VERROR(ret, NULL,
  25464. "The type definition is absent");
  25465. goto exit;
  25466. }
  25467. if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
  25468. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25469. ret = XML_SCHEMAV_CVC_TYPE_2;
  25470. VERROR(ret, NULL,
  25471. "The type definition is abstract");
  25472. goto exit;
  25473. }
  25474. /*
  25475. * Evaluate IDCs. Do it here, since new IDC matchers are registered
  25476. * during validation against the declaration. This must be done
  25477. * _before_ attribute validation.
  25478. */
  25479. if (vctxt->xpathStates != NULL) {
  25480. ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
  25481. vctxt->inode->appliedXPath = 1;
  25482. if (ret == -1) {
  25483. VERROR_INT("xmlSchemaValidateElem",
  25484. "calling xmlSchemaXPathEvaluate()");
  25485. goto internal_error;
  25486. }
  25487. }
  25488. /*
  25489. * Validate attributes.
  25490. */
  25491. if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
  25492. if ((vctxt->nbAttrInfos != 0) ||
  25493. (vctxt->inode->typeDef->attrUses != NULL)) {
  25494. ret = xmlSchemaVAttributesComplex(vctxt);
  25495. }
  25496. } else if (vctxt->nbAttrInfos != 0) {
  25497. ret = xmlSchemaVAttributesSimple(vctxt);
  25498. }
  25499. /*
  25500. * Clear registered attributes.
  25501. */
  25502. if (vctxt->nbAttrInfos != 0)
  25503. xmlSchemaClearAttrInfos(vctxt);
  25504. if (ret == -1) {
  25505. VERROR_INT("xmlSchemaValidateElem",
  25506. "calling attributes validation");
  25507. goto internal_error;
  25508. }
  25509. /*
  25510. * Don't return an error if attributes are invalid on purpose.
  25511. */
  25512. ret = 0;
  25513. exit:
  25514. if (ret != 0)
  25515. vctxt->skipDepth = vctxt->depth;
  25516. return (ret);
  25517. internal_error:
  25518. return (-1);
  25519. }
  25520. #ifdef XML_SCHEMA_READER_ENABLED
  25521. static int
  25522. xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
  25523. {
  25524. const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
  25525. int depth, nodeType, ret = 0, consumed;
  25526. xmlSchemaNodeInfoPtr ielem;
  25527. vctxt->depth = -1;
  25528. ret = xmlTextReaderRead(vctxt->reader);
  25529. /*
  25530. * Move to the document element.
  25531. */
  25532. while (ret == 1) {
  25533. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25534. if (nodeType == XML_ELEMENT_NODE)
  25535. goto root_found;
  25536. ret = xmlTextReaderRead(vctxt->reader);
  25537. }
  25538. goto exit;
  25539. root_found:
  25540. do {
  25541. depth = xmlTextReaderDepth(vctxt->reader);
  25542. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25543. if (nodeType == XML_ELEMENT_NODE) {
  25544. vctxt->depth++;
  25545. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25546. VERROR_INT("xmlSchemaVReaderWalk",
  25547. "calling xmlSchemaValidatorPushElem()");
  25548. goto internal_error;
  25549. }
  25550. ielem = vctxt->inode;
  25551. ielem->localName = xmlTextReaderLocalName(vctxt->reader);
  25552. ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
  25553. ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  25554. /*
  25555. * Is the element empty?
  25556. */
  25557. ret = xmlTextReaderIsEmptyElement(vctxt->reader);
  25558. if (ret == -1) {
  25559. VERROR_INT("xmlSchemaVReaderWalk",
  25560. "calling xmlTextReaderIsEmptyElement()");
  25561. goto internal_error;
  25562. }
  25563. if (ret) {
  25564. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25565. }
  25566. /*
  25567. * Register attributes.
  25568. */
  25569. vctxt->nbAttrInfos = 0;
  25570. ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
  25571. if (ret == -1) {
  25572. VERROR_INT("xmlSchemaVReaderWalk",
  25573. "calling xmlTextReaderMoveToFirstAttribute()");
  25574. goto internal_error;
  25575. }
  25576. if (ret == 1) {
  25577. do {
  25578. /*
  25579. * VAL TODO: How do we know that the reader works on a
  25580. * node tree, to be able to pass a node here?
  25581. */
  25582. if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
  25583. (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
  25584. xmlTextReaderNamespaceUri(vctxt->reader), 1,
  25585. xmlTextReaderValue(vctxt->reader), 1) == -1) {
  25586. VERROR_INT("xmlSchemaVReaderWalk",
  25587. "calling xmlSchemaValidatorPushAttribute()");
  25588. goto internal_error;
  25589. }
  25590. ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
  25591. if (ret == -1) {
  25592. VERROR_INT("xmlSchemaVReaderWalk",
  25593. "calling xmlTextReaderMoveToFirstAttribute()");
  25594. goto internal_error;
  25595. }
  25596. } while (ret == 1);
  25597. /*
  25598. * Back to element position.
  25599. */
  25600. ret = xmlTextReaderMoveToElement(vctxt->reader);
  25601. if (ret == -1) {
  25602. VERROR_INT("xmlSchemaVReaderWalk",
  25603. "calling xmlTextReaderMoveToElement()");
  25604. goto internal_error;
  25605. }
  25606. }
  25607. /*
  25608. * Validate the element.
  25609. */
  25610. ret= xmlSchemaValidateElem(vctxt);
  25611. if (ret != 0) {
  25612. if (ret == -1) {
  25613. VERROR_INT("xmlSchemaVReaderWalk",
  25614. "calling xmlSchemaValidateElem()");
  25615. goto internal_error;
  25616. }
  25617. goto exit;
  25618. }
  25619. if (vctxt->depth == vctxt->skipDepth) {
  25620. int curDepth;
  25621. /*
  25622. * Skip all content.
  25623. */
  25624. if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
  25625. ret = xmlTextReaderRead(vctxt->reader);
  25626. curDepth = xmlTextReaderDepth(vctxt->reader);
  25627. while ((ret == 1) && (curDepth != depth)) {
  25628. ret = xmlTextReaderRead(vctxt->reader);
  25629. curDepth = xmlTextReaderDepth(vctxt->reader);
  25630. }
  25631. if (ret < 0) {
  25632. /*
  25633. * VAL TODO: A reader error occured; what to do here?
  25634. */
  25635. ret = 1;
  25636. goto exit;
  25637. }
  25638. }
  25639. goto leave_elem;
  25640. }
  25641. /*
  25642. * READER VAL TODO: Is an END_ELEM really never called
  25643. * if the elem is empty?
  25644. */
  25645. if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25646. goto leave_elem;
  25647. } else if (nodeType == END_ELEM) {
  25648. /*
  25649. * Process END of element.
  25650. */
  25651. leave_elem:
  25652. ret = xmlSchemaValidatorPopElem(vctxt);
  25653. if (ret != 0) {
  25654. if (ret < 0) {
  25655. VERROR_INT("xmlSchemaVReaderWalk",
  25656. "calling xmlSchemaValidatorPopElem()");
  25657. goto internal_error;
  25658. }
  25659. goto exit;
  25660. }
  25661. if (vctxt->depth >= 0)
  25662. ielem = vctxt->inode;
  25663. else
  25664. ielem = NULL;
  25665. } else if ((nodeType == XML_TEXT_NODE) ||
  25666. (nodeType == XML_CDATA_SECTION_NODE) ||
  25667. (nodeType == WHTSP) ||
  25668. (nodeType == SIGN_WHTSP)) {
  25669. /*
  25670. * Process character content.
  25671. */
  25672. xmlChar *value;
  25673. if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
  25674. nodeType = XML_TEXT_NODE;
  25675. value = xmlTextReaderValue(vctxt->reader);
  25676. ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
  25677. -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
  25678. if (! consumed)
  25679. xmlFree(value);
  25680. if (ret == -1) {
  25681. VERROR_INT("xmlSchemaVReaderWalk",
  25682. "calling xmlSchemaVPushText()");
  25683. goto internal_error;
  25684. }
  25685. } else if ((nodeType == XML_ENTITY_NODE) ||
  25686. (nodeType == XML_ENTITY_REF_NODE)) {
  25687. /*
  25688. * VAL TODO: What to do with entities?
  25689. */
  25690. TODO
  25691. }
  25692. /*
  25693. * Read next node.
  25694. */
  25695. ret = xmlTextReaderRead(vctxt->reader);
  25696. } while (ret == 1);
  25697. exit:
  25698. return (ret);
  25699. internal_error:
  25700. return (-1);
  25701. }
  25702. #endif
  25703. /************************************************************************
  25704. * *
  25705. * SAX validation handlers *
  25706. * *
  25707. ************************************************************************/
  25708. /*
  25709. * Process text content.
  25710. */
  25711. static void
  25712. xmlSchemaSAXHandleText(void *ctx,
  25713. const xmlChar * ch,
  25714. int len)
  25715. {
  25716. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25717. if (vctxt->depth < 0)
  25718. return;
  25719. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25720. return;
  25721. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25722. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25723. if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
  25724. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25725. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25726. "calling xmlSchemaVPushText()");
  25727. vctxt->err = -1;
  25728. xmlStopParser(vctxt->parserCtxt);
  25729. }
  25730. }
  25731. /*
  25732. * Process CDATA content.
  25733. */
  25734. static void
  25735. xmlSchemaSAXHandleCDataSection(void *ctx,
  25736. const xmlChar * ch,
  25737. int len)
  25738. {
  25739. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25740. if (vctxt->depth < 0)
  25741. return;
  25742. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25743. return;
  25744. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25745. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25746. if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
  25747. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25748. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25749. "calling xmlSchemaVPushText()");
  25750. vctxt->err = -1;
  25751. xmlStopParser(vctxt->parserCtxt);
  25752. }
  25753. }
  25754. static void
  25755. xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
  25756. const xmlChar * name ATTRIBUTE_UNUSED)
  25757. {
  25758. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25759. if (vctxt->depth < 0)
  25760. return;
  25761. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25762. return;
  25763. /* SAX VAL TODO: What to do here? */
  25764. TODO
  25765. }
  25766. static void
  25767. xmlSchemaSAXHandleStartElementNs(void *ctx,
  25768. const xmlChar * localname,
  25769. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25770. const xmlChar * URI,
  25771. int nb_namespaces,
  25772. const xmlChar ** namespaces,
  25773. int nb_attributes,
  25774. int nb_defaulted ATTRIBUTE_UNUSED,
  25775. const xmlChar ** attributes)
  25776. {
  25777. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25778. int ret;
  25779. xmlSchemaNodeInfoPtr ielem;
  25780. int i, j;
  25781. /*
  25782. * SAX VAL TODO: What to do with nb_defaulted?
  25783. */
  25784. /*
  25785. * Skip elements if inside a "skip" wildcard or invalid.
  25786. */
  25787. vctxt->depth++;
  25788. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25789. return;
  25790. /*
  25791. * Push the element.
  25792. */
  25793. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25794. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25795. "calling xmlSchemaValidatorPushElem()");
  25796. goto internal_error;
  25797. }
  25798. ielem = vctxt->inode;
  25799. /*
  25800. * TODO: Is this OK?
  25801. */
  25802. ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
  25803. ielem->localName = localname;
  25804. ielem->nsName = URI;
  25805. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25806. /*
  25807. * Register namespaces on the elem info.
  25808. */
  25809. if (nb_namespaces != 0) {
  25810. /*
  25811. * Although the parser builds its own namespace list,
  25812. * we have no access to it, so we'll use an own one.
  25813. */
  25814. for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
  25815. /*
  25816. * Store prefix and namespace name.
  25817. */
  25818. if (ielem->nsBindings == NULL) {
  25819. ielem->nsBindings =
  25820. (const xmlChar **) xmlMalloc(10 *
  25821. sizeof(const xmlChar *));
  25822. if (ielem->nsBindings == NULL) {
  25823. xmlSchemaVErrMemory(vctxt,
  25824. "allocating namespace bindings for SAX validation",
  25825. NULL);
  25826. goto internal_error;
  25827. }
  25828. ielem->nbNsBindings = 0;
  25829. ielem->sizeNsBindings = 5;
  25830. } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
  25831. ielem->sizeNsBindings *= 2;
  25832. ielem->nsBindings =
  25833. (const xmlChar **) xmlRealloc(
  25834. (void *) ielem->nsBindings,
  25835. ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
  25836. if (ielem->nsBindings == NULL) {
  25837. xmlSchemaVErrMemory(vctxt,
  25838. "re-allocating namespace bindings for SAX validation",
  25839. NULL);
  25840. goto internal_error;
  25841. }
  25842. }
  25843. ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
  25844. if (namespaces[j+1][0] == 0) {
  25845. /*
  25846. * Handle xmlns="".
  25847. */
  25848. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
  25849. } else
  25850. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
  25851. namespaces[j+1];
  25852. ielem->nbNsBindings++;
  25853. }
  25854. }
  25855. /*
  25856. * Register attributes.
  25857. * SAX VAL TODO: We are not adding namespace declaration
  25858. * attributes yet.
  25859. */
  25860. if (nb_attributes != 0) {
  25861. xmlChar *value;
  25862. for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
  25863. /*
  25864. * Duplicate the value.
  25865. */
  25866. value = xmlStrndup(attributes[j+3],
  25867. attributes[j+4] - attributes[j+3]);
  25868. /*
  25869. * TODO: Set the node line.
  25870. */
  25871. ret = xmlSchemaValidatorPushAttribute(vctxt,
  25872. NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
  25873. value, 1);
  25874. if (ret == -1) {
  25875. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25876. "calling xmlSchemaValidatorPushAttribute()");
  25877. goto internal_error;
  25878. }
  25879. }
  25880. }
  25881. /*
  25882. * Validate the element.
  25883. */
  25884. ret = xmlSchemaValidateElem(vctxt);
  25885. if (ret != 0) {
  25886. if (ret == -1) {
  25887. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25888. "calling xmlSchemaValidateElem()");
  25889. goto internal_error;
  25890. }
  25891. goto exit;
  25892. }
  25893. exit:
  25894. return;
  25895. internal_error:
  25896. vctxt->err = -1;
  25897. xmlStopParser(vctxt->parserCtxt);
  25898. return;
  25899. }
  25900. static void
  25901. xmlSchemaSAXHandleEndElementNs(void *ctx,
  25902. const xmlChar * localname ATTRIBUTE_UNUSED,
  25903. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25904. const xmlChar * URI ATTRIBUTE_UNUSED)
  25905. {
  25906. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25907. int res;
  25908. /*
  25909. * Skip elements if inside a "skip" wildcard or if invalid.
  25910. */
  25911. if (vctxt->skipDepth != -1) {
  25912. if (vctxt->depth > vctxt->skipDepth) {
  25913. vctxt->depth--;
  25914. return;
  25915. } else
  25916. vctxt->skipDepth = -1;
  25917. }
  25918. /*
  25919. * SAX VAL TODO: Just a temporary check.
  25920. */
  25921. if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
  25922. (!xmlStrEqual(vctxt->inode->nsName, URI))) {
  25923. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  25924. "elem pop mismatch");
  25925. }
  25926. res = xmlSchemaValidatorPopElem(vctxt);
  25927. if (res != 0) {
  25928. if (res < 0) {
  25929. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  25930. "calling xmlSchemaValidatorPopElem()");
  25931. goto internal_error;
  25932. }
  25933. goto exit;
  25934. }
  25935. exit:
  25936. return;
  25937. internal_error:
  25938. vctxt->err = -1;
  25939. xmlStopParser(vctxt->parserCtxt);
  25940. return;
  25941. }
  25942. /************************************************************************
  25943. * *
  25944. * Validation interfaces *
  25945. * *
  25946. ************************************************************************/
  25947. /**
  25948. * xmlSchemaNewValidCtxt:
  25949. * @schema: a precompiled XML Schemas
  25950. *
  25951. * Create an XML Schemas validation context based on the given schema.
  25952. *
  25953. * Returns the validation context or NULL in case of error
  25954. */
  25955. xmlSchemaValidCtxtPtr
  25956. xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
  25957. {
  25958. xmlSchemaValidCtxtPtr ret;
  25959. ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
  25960. if (ret == NULL) {
  25961. xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
  25962. return (NULL);
  25963. }
  25964. memset(ret, 0, sizeof(xmlSchemaValidCtxt));
  25965. ret->type = XML_SCHEMA_CTXT_VALIDATOR;
  25966. ret->dict = xmlDictCreate();
  25967. ret->nodeQNames = xmlSchemaItemListCreate();
  25968. ret->schema = schema;
  25969. return (ret);
  25970. }
  25971. /**
  25972. * xmlSchemaClearValidCtxt:
  25973. * @ctxt: the schema validation context
  25974. *
  25975. * Free the resources associated to the schema validation context;
  25976. * leaves some fields alive intended for reuse of the context.
  25977. */
  25978. static void
  25979. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
  25980. {
  25981. if (vctxt == NULL)
  25982. return;
  25983. /*
  25984. * TODO: Should we clear the flags?
  25985. * Might be problematic if one reuses the context
  25986. * and assumes that the options remain the same.
  25987. */
  25988. vctxt->flags = 0;
  25989. vctxt->validationRoot = NULL;
  25990. vctxt->doc = NULL;
  25991. #ifdef LIBXML_READER_ENABLED
  25992. vctxt->reader = NULL;
  25993. #endif
  25994. vctxt->hasKeyrefs = 0;
  25995. if (vctxt->value != NULL) {
  25996. xmlSchemaFreeValue(vctxt->value);
  25997. vctxt->value = NULL;
  25998. }
  25999. /*
  26000. * Augmented IDC information.
  26001. */
  26002. if (vctxt->aidcs != NULL) {
  26003. xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
  26004. do {
  26005. next = cur->next;
  26006. xmlFree(cur);
  26007. cur = next;
  26008. } while (cur != NULL);
  26009. vctxt->aidcs = NULL;
  26010. }
  26011. if (vctxt->idcMatcherCache != NULL) {
  26012. xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
  26013. while (matcher) {
  26014. tmp = matcher;
  26015. matcher = matcher->nextCached;
  26016. xmlSchemaIDCFreeMatcherList(tmp);
  26017. }
  26018. vctxt->idcMatcherCache = NULL;
  26019. }
  26020. if (vctxt->idcNodes != NULL) {
  26021. int i;
  26022. xmlSchemaPSVIIDCNodePtr item;
  26023. for (i = 0; i < vctxt->nbIdcNodes; i++) {
  26024. item = vctxt->idcNodes[i];
  26025. xmlFree(item->keys);
  26026. xmlFree(item);
  26027. }
  26028. xmlFree(vctxt->idcNodes);
  26029. vctxt->idcNodes = NULL;
  26030. vctxt->nbIdcNodes = 0;
  26031. vctxt->sizeIdcNodes = 0;
  26032. }
  26033. /*
  26034. * Note that we won't delete the XPath state pool here.
  26035. */
  26036. if (vctxt->xpathStates != NULL) {
  26037. xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
  26038. vctxt->xpathStates = NULL;
  26039. }
  26040. /*
  26041. * Attribute info.
  26042. */
  26043. if (vctxt->nbAttrInfos != 0) {
  26044. xmlSchemaClearAttrInfos(vctxt);
  26045. }
  26046. /*
  26047. * Element info.
  26048. */
  26049. if (vctxt->elemInfos != NULL) {
  26050. int i;
  26051. xmlSchemaNodeInfoPtr ei;
  26052. for (i = 0; i < vctxt->sizeElemInfos; i++) {
  26053. ei = vctxt->elemInfos[i];
  26054. if (ei == NULL)
  26055. break;
  26056. xmlSchemaClearElemInfo(vctxt, ei);
  26057. }
  26058. }
  26059. xmlSchemaItemListClear(vctxt->nodeQNames);
  26060. /* Recreate the dict. */
  26061. xmlDictFree(vctxt->dict);
  26062. /*
  26063. * TODO: Is is save to recreate it? Do we have a scenario
  26064. * where the user provides the dict?
  26065. */
  26066. vctxt->dict = xmlDictCreate();
  26067. }
  26068. /**
  26069. * xmlSchemaFreeValidCtxt:
  26070. * @ctxt: the schema validation context
  26071. *
  26072. * Free the resources associated to the schema validation context
  26073. */
  26074. void
  26075. xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
  26076. {
  26077. if (ctxt == NULL)
  26078. return;
  26079. if (ctxt->value != NULL)
  26080. xmlSchemaFreeValue(ctxt->value);
  26081. if (ctxt->pctxt != NULL)
  26082. xmlSchemaFreeParserCtxt(ctxt->pctxt);
  26083. if (ctxt->idcNodes != NULL) {
  26084. int i;
  26085. xmlSchemaPSVIIDCNodePtr item;
  26086. for (i = 0; i < ctxt->nbIdcNodes; i++) {
  26087. item = ctxt->idcNodes[i];
  26088. xmlFree(item->keys);
  26089. xmlFree(item);
  26090. }
  26091. xmlFree(ctxt->idcNodes);
  26092. }
  26093. if (ctxt->idcKeys != NULL) {
  26094. int i;
  26095. for (i = 0; i < ctxt->nbIdcKeys; i++)
  26096. xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
  26097. xmlFree(ctxt->idcKeys);
  26098. }
  26099. if (ctxt->xpathStates != NULL) {
  26100. xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
  26101. ctxt->xpathStates = NULL;
  26102. }
  26103. if (ctxt->xpathStatePool != NULL) {
  26104. xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
  26105. ctxt->xpathStatePool = NULL;
  26106. }
  26107. /*
  26108. * Augmented IDC information.
  26109. */
  26110. if (ctxt->aidcs != NULL) {
  26111. xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
  26112. do {
  26113. next = cur->next;
  26114. xmlFree(cur);
  26115. cur = next;
  26116. } while (cur != NULL);
  26117. }
  26118. if (ctxt->attrInfos != NULL) {
  26119. int i;
  26120. xmlSchemaAttrInfoPtr attr;
  26121. /* Just a paranoid call to the cleanup. */
  26122. if (ctxt->nbAttrInfos != 0)
  26123. xmlSchemaClearAttrInfos(ctxt);
  26124. for (i = 0; i < ctxt->sizeAttrInfos; i++) {
  26125. attr = ctxt->attrInfos[i];
  26126. xmlFree(attr);
  26127. }
  26128. xmlFree(ctxt->attrInfos);
  26129. }
  26130. if (ctxt->elemInfos != NULL) {
  26131. int i;
  26132. xmlSchemaNodeInfoPtr ei;
  26133. for (i = 0; i < ctxt->sizeElemInfos; i++) {
  26134. ei = ctxt->elemInfos[i];
  26135. if (ei == NULL)
  26136. break;
  26137. xmlSchemaClearElemInfo(ctxt, ei);
  26138. xmlFree(ei);
  26139. }
  26140. xmlFree(ctxt->elemInfos);
  26141. }
  26142. if (ctxt->nodeQNames != NULL)
  26143. xmlSchemaItemListFree(ctxt->nodeQNames);
  26144. if (ctxt->dict != NULL)
  26145. xmlDictFree(ctxt->dict);
  26146. xmlFree(ctxt);
  26147. }
  26148. /**
  26149. * xmlSchemaIsValid:
  26150. * @ctxt: the schema validation context
  26151. *
  26152. * Check if any error was detected during validation.
  26153. *
  26154. * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
  26155. * of internal error.
  26156. */
  26157. int
  26158. xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
  26159. {
  26160. if (ctxt == NULL)
  26161. return(-1);
  26162. return(ctxt->err == 0);
  26163. }
  26164. /**
  26165. * xmlSchemaSetValidErrors:
  26166. * @ctxt: a schema validation context
  26167. * @err: the error function
  26168. * @warn: the warning function
  26169. * @ctx: the functions context
  26170. *
  26171. * Set the error and warning callback informations
  26172. */
  26173. void
  26174. xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26175. xmlSchemaValidityErrorFunc err,
  26176. xmlSchemaValidityWarningFunc warn, void *ctx)
  26177. {
  26178. if (ctxt == NULL)
  26179. return;
  26180. ctxt->error = err;
  26181. ctxt->warning = warn;
  26182. ctxt->errCtxt = ctx;
  26183. if (ctxt->pctxt != NULL)
  26184. xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
  26185. }
  26186. /**
  26187. * xmlSchemaSetValidStructuredErrors:
  26188. * @ctxt: a schema validation context
  26189. * @serror: the structured error function
  26190. * @ctx: the functions context
  26191. *
  26192. * Set the structured error callback
  26193. */
  26194. void
  26195. xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
  26196. xmlStructuredErrorFunc serror, void *ctx)
  26197. {
  26198. if (ctxt == NULL)
  26199. return;
  26200. ctxt->serror = serror;
  26201. ctxt->error = NULL;
  26202. ctxt->warning = NULL;
  26203. ctxt->errCtxt = ctx;
  26204. if (ctxt->pctxt != NULL)
  26205. xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
  26206. }
  26207. /**
  26208. * xmlSchemaGetValidErrors:
  26209. * @ctxt: a XML-Schema validation context
  26210. * @err: the error function result
  26211. * @warn: the warning function result
  26212. * @ctx: the functions context result
  26213. *
  26214. * Get the error and warning callback informations
  26215. *
  26216. * Returns -1 in case of error and 0 otherwise
  26217. */
  26218. int
  26219. xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26220. xmlSchemaValidityErrorFunc * err,
  26221. xmlSchemaValidityWarningFunc * warn, void **ctx)
  26222. {
  26223. if (ctxt == NULL)
  26224. return (-1);
  26225. if (err != NULL)
  26226. *err = ctxt->error;
  26227. if (warn != NULL)
  26228. *warn = ctxt->warning;
  26229. if (ctx != NULL)
  26230. *ctx = ctxt->errCtxt;
  26231. return (0);
  26232. }
  26233. /**
  26234. * xmlSchemaSetValidOptions:
  26235. * @ctxt: a schema validation context
  26236. * @options: a combination of xmlSchemaValidOption
  26237. *
  26238. * Sets the options to be used during the validation.
  26239. *
  26240. * Returns 0 in case of success, -1 in case of an
  26241. * API error.
  26242. */
  26243. int
  26244. xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
  26245. int options)
  26246. {
  26247. int i;
  26248. if (ctxt == NULL)
  26249. return (-1);
  26250. /*
  26251. * WARNING: Change the start value if adding to the
  26252. * xmlSchemaValidOption.
  26253. * TODO: Is there an other, more easy to maintain,
  26254. * way?
  26255. */
  26256. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  26257. if (options & 1<<i)
  26258. return (-1);
  26259. }
  26260. ctxt->options = options;
  26261. return (0);
  26262. }
  26263. /**
  26264. * xmlSchemaValidCtxtGetOptions:
  26265. * @ctxt: a schema validation context
  26266. *
  26267. * Get the validation context options.
  26268. *
  26269. * Returns the option combination or -1 on error.
  26270. */
  26271. int
  26272. xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
  26273. {
  26274. if (ctxt == NULL)
  26275. return (-1);
  26276. else
  26277. return (ctxt->options);
  26278. }
  26279. static int
  26280. xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
  26281. {
  26282. xmlAttrPtr attr;
  26283. int ret = 0;
  26284. xmlSchemaNodeInfoPtr ielem = NULL;
  26285. xmlNodePtr node, valRoot;
  26286. const xmlChar *nsName;
  26287. /* DOC VAL TODO: Move this to the start function. */
  26288. valRoot = xmlDocGetRootElement(vctxt->doc);
  26289. if (valRoot == NULL) {
  26290. /* VAL TODO: Error code? */
  26291. VERROR(1, NULL, "The document has no document element");
  26292. return (1);
  26293. }
  26294. vctxt->depth = -1;
  26295. vctxt->validationRoot = valRoot;
  26296. node = valRoot;
  26297. while (node != NULL) {
  26298. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26299. goto next_sibling;
  26300. if (node->type == XML_ELEMENT_NODE) {
  26301. /*
  26302. * Init the node-info.
  26303. */
  26304. vctxt->depth++;
  26305. if (xmlSchemaValidatorPushElem(vctxt) == -1)
  26306. goto internal_error;
  26307. ielem = vctxt->inode;
  26308. ielem->node = node;
  26309. ielem->nodeLine = node->line;
  26310. ielem->localName = node->name;
  26311. if (node->ns != NULL)
  26312. ielem->nsName = node->ns->href;
  26313. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26314. /*
  26315. * Register attributes.
  26316. * DOC VAL TODO: We do not register namespace declaration
  26317. * attributes yet.
  26318. */
  26319. vctxt->nbAttrInfos = 0;
  26320. if (node->properties != NULL) {
  26321. attr = node->properties;
  26322. do {
  26323. if (attr->ns != NULL)
  26324. nsName = attr->ns->href;
  26325. else
  26326. nsName = NULL;
  26327. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26328. (xmlNodePtr) attr,
  26329. /*
  26330. * Note that we give it the line number of the
  26331. * parent element.
  26332. */
  26333. ielem->nodeLine,
  26334. attr->name, nsName, 0,
  26335. xmlNodeListGetString(attr->doc, attr->children, 1), 1);
  26336. if (ret == -1) {
  26337. VERROR_INT("xmlSchemaDocWalk",
  26338. "calling xmlSchemaValidatorPushAttribute()");
  26339. goto internal_error;
  26340. }
  26341. attr = attr->next;
  26342. } while (attr);
  26343. }
  26344. /*
  26345. * Validate the element.
  26346. */
  26347. ret = xmlSchemaValidateElem(vctxt);
  26348. if (ret != 0) {
  26349. if (ret == -1) {
  26350. VERROR_INT("xmlSchemaDocWalk",
  26351. "calling xmlSchemaValidateElem()");
  26352. goto internal_error;
  26353. }
  26354. /*
  26355. * Don't stop validation; just skip the content
  26356. * of this element.
  26357. */
  26358. goto leave_node;
  26359. }
  26360. if ((vctxt->skipDepth != -1) &&
  26361. (vctxt->depth >= vctxt->skipDepth))
  26362. goto leave_node;
  26363. } else if ((node->type == XML_TEXT_NODE) ||
  26364. (node->type == XML_CDATA_SECTION_NODE)) {
  26365. /*
  26366. * Process character content.
  26367. */
  26368. if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
  26369. ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26370. ret = xmlSchemaVPushText(vctxt, node->type, node->content,
  26371. -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
  26372. if (ret < 0) {
  26373. VERROR_INT("xmlSchemaVDocWalk",
  26374. "calling xmlSchemaVPushText()");
  26375. goto internal_error;
  26376. }
  26377. /*
  26378. * DOC VAL TODO: Should we skip further validation of the
  26379. * element content here?
  26380. */
  26381. } else if ((node->type == XML_ENTITY_NODE) ||
  26382. (node->type == XML_ENTITY_REF_NODE)) {
  26383. /*
  26384. * DOC VAL TODO: What to do with entities?
  26385. */
  26386. VERROR_INT("xmlSchemaVDocWalk",
  26387. "there is at least one entity reference in the node-tree "
  26388. "currently being validated. Processing of entities with "
  26389. "this XML Schema processor is not supported (yet). Please "
  26390. "substitute entities before validation.");
  26391. goto internal_error;
  26392. } else {
  26393. goto leave_node;
  26394. /*
  26395. * DOC VAL TODO: XInclude nodes, etc.
  26396. */
  26397. }
  26398. /*
  26399. * Walk the doc.
  26400. */
  26401. if (node->children != NULL) {
  26402. node = node->children;
  26403. continue;
  26404. }
  26405. leave_node:
  26406. if (node->type == XML_ELEMENT_NODE) {
  26407. /*
  26408. * Leaving the scope of an element.
  26409. */
  26410. if (node != vctxt->inode->node) {
  26411. VERROR_INT("xmlSchemaVDocWalk",
  26412. "element position mismatch");
  26413. goto internal_error;
  26414. }
  26415. ret = xmlSchemaValidatorPopElem(vctxt);
  26416. if (ret != 0) {
  26417. if (ret < 0) {
  26418. VERROR_INT("xmlSchemaVDocWalk",
  26419. "calling xmlSchemaValidatorPopElem()");
  26420. goto internal_error;
  26421. }
  26422. }
  26423. if (node == valRoot)
  26424. goto exit;
  26425. }
  26426. next_sibling:
  26427. if (node->next != NULL)
  26428. node = node->next;
  26429. else {
  26430. node = node->parent;
  26431. goto leave_node;
  26432. }
  26433. }
  26434. exit:
  26435. return (ret);
  26436. internal_error:
  26437. return (-1);
  26438. }
  26439. static int
  26440. xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
  26441. /*
  26442. * Some initialization.
  26443. */
  26444. vctxt->err = 0;
  26445. vctxt->nberrors = 0;
  26446. vctxt->depth = -1;
  26447. vctxt->skipDepth = -1;
  26448. vctxt->xsiAssemble = 0;
  26449. vctxt->hasKeyrefs = 0;
  26450. #ifdef ENABLE_IDC_NODE_TABLES_TEST
  26451. vctxt->createIDCNodeTables = 1;
  26452. #else
  26453. vctxt->createIDCNodeTables = 0;
  26454. #endif
  26455. /*
  26456. * Create a schema + parser if necessary.
  26457. */
  26458. if (vctxt->schema == NULL) {
  26459. xmlSchemaParserCtxtPtr pctxt;
  26460. vctxt->xsiAssemble = 1;
  26461. /*
  26462. * If not schema was given then we will create a schema
  26463. * dynamically using XSI schema locations.
  26464. *
  26465. * Create the schema parser context.
  26466. */
  26467. if ((vctxt->pctxt == NULL) &&
  26468. (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  26469. return (-1);
  26470. pctxt = vctxt->pctxt;
  26471. pctxt->xsiAssemble = 1;
  26472. /*
  26473. * Create the schema.
  26474. */
  26475. vctxt->schema = xmlSchemaNewSchema(pctxt);
  26476. if (vctxt->schema == NULL)
  26477. return (-1);
  26478. /*
  26479. * Create the schema construction context.
  26480. */
  26481. pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
  26482. if (pctxt->constructor == NULL)
  26483. return(-1);
  26484. pctxt->constructor->mainSchema = vctxt->schema;
  26485. /*
  26486. * Take ownership of the constructor to be able to free it.
  26487. */
  26488. pctxt->ownsConstructor = 1;
  26489. }
  26490. /*
  26491. * Augment the IDC definitions for the main schema and all imported ones
  26492. * NOTE: main schema if the first in the imported list
  26493. */
  26494. xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
  26495. return(0);
  26496. }
  26497. static void
  26498. xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
  26499. if (vctxt->xsiAssemble) {
  26500. if (vctxt->schema != NULL) {
  26501. xmlSchemaFree(vctxt->schema);
  26502. vctxt->schema = NULL;
  26503. }
  26504. }
  26505. xmlSchemaClearValidCtxt(vctxt);
  26506. }
  26507. static int
  26508. xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
  26509. {
  26510. int ret = 0;
  26511. if (xmlSchemaPreRun(vctxt) < 0)
  26512. return(-1);
  26513. if (vctxt->doc != NULL) {
  26514. /*
  26515. * Tree validation.
  26516. */
  26517. ret = xmlSchemaVDocWalk(vctxt);
  26518. #ifdef LIBXML_READER_ENABLED
  26519. } else if (vctxt->reader != NULL) {
  26520. /*
  26521. * XML Reader validation.
  26522. */
  26523. #ifdef XML_SCHEMA_READER_ENABLED
  26524. ret = xmlSchemaVReaderWalk(vctxt);
  26525. #endif
  26526. #endif
  26527. } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
  26528. /*
  26529. * SAX validation.
  26530. */
  26531. ret = xmlParseDocument(vctxt->parserCtxt);
  26532. } else {
  26533. VERROR_INT("xmlSchemaVStart",
  26534. "no instance to validate");
  26535. ret = -1;
  26536. }
  26537. xmlSchemaPostRun(vctxt);
  26538. if (ret == 0)
  26539. ret = vctxt->err;
  26540. return (ret);
  26541. }
  26542. /**
  26543. * xmlSchemaValidateOneElement:
  26544. * @ctxt: a schema validation context
  26545. * @elem: an element node
  26546. *
  26547. * Validate a branch of a tree, starting with the given @elem.
  26548. *
  26549. * Returns 0 if the element and its subtree is valid, a positive error
  26550. * code number otherwise and -1 in case of an internal or API error.
  26551. */
  26552. int
  26553. xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
  26554. {
  26555. if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
  26556. return (-1);
  26557. if (ctxt->schema == NULL)
  26558. return (-1);
  26559. ctxt->doc = elem->doc;
  26560. ctxt->node = elem;
  26561. ctxt->validationRoot = elem;
  26562. return(xmlSchemaVStart(ctxt));
  26563. }
  26564. /**
  26565. * xmlSchemaValidateDoc:
  26566. * @ctxt: a schema validation context
  26567. * @doc: a parsed document tree
  26568. *
  26569. * Validate a document tree in memory.
  26570. *
  26571. * Returns 0 if the document is schemas valid, a positive error code
  26572. * number otherwise and -1 in case of internal or API error.
  26573. */
  26574. int
  26575. xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
  26576. {
  26577. if ((ctxt == NULL) || (doc == NULL))
  26578. return (-1);
  26579. ctxt->doc = doc;
  26580. ctxt->node = xmlDocGetRootElement(doc);
  26581. if (ctxt->node == NULL) {
  26582. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  26583. XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
  26584. (xmlNodePtr) doc, NULL,
  26585. "The document has no document element", NULL, NULL);
  26586. return (ctxt->err);
  26587. }
  26588. ctxt->validationRoot = ctxt->node;
  26589. return (xmlSchemaVStart(ctxt));
  26590. }
  26591. /************************************************************************
  26592. * *
  26593. * Function and data for SAX streaming API *
  26594. * *
  26595. ************************************************************************/
  26596. typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
  26597. typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
  26598. struct _xmlSchemaSplitSAXData {
  26599. xmlSAXHandlerPtr user_sax;
  26600. void *user_data;
  26601. xmlSchemaValidCtxtPtr ctxt;
  26602. xmlSAXHandlerPtr schemas_sax;
  26603. };
  26604. #define XML_SAX_PLUG_MAGIC 0xdc43ba21
  26605. struct _xmlSchemaSAXPlug {
  26606. unsigned int magic;
  26607. /* the original callbacks informations */
  26608. xmlSAXHandlerPtr *user_sax_ptr;
  26609. xmlSAXHandlerPtr user_sax;
  26610. void **user_data_ptr;
  26611. void *user_data;
  26612. /* the block plugged back and validation informations */
  26613. xmlSAXHandler schemas_sax;
  26614. xmlSchemaValidCtxtPtr ctxt;
  26615. };
  26616. /* All those functions just bounces to the user provided SAX handlers */
  26617. static void
  26618. internalSubsetSplit(void *ctx, const xmlChar *name,
  26619. const xmlChar *ExternalID, const xmlChar *SystemID)
  26620. {
  26621. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26622. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26623. (ctxt->user_sax->internalSubset != NULL))
  26624. ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
  26625. SystemID);
  26626. }
  26627. static int
  26628. isStandaloneSplit(void *ctx)
  26629. {
  26630. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26631. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26632. (ctxt->user_sax->isStandalone != NULL))
  26633. return(ctxt->user_sax->isStandalone(ctxt->user_data));
  26634. return(0);
  26635. }
  26636. static int
  26637. hasInternalSubsetSplit(void *ctx)
  26638. {
  26639. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26640. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26641. (ctxt->user_sax->hasInternalSubset != NULL))
  26642. return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
  26643. return(0);
  26644. }
  26645. static int
  26646. hasExternalSubsetSplit(void *ctx)
  26647. {
  26648. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26649. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26650. (ctxt->user_sax->hasExternalSubset != NULL))
  26651. return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
  26652. return(0);
  26653. }
  26654. static void
  26655. externalSubsetSplit(void *ctx, const xmlChar *name,
  26656. const xmlChar *ExternalID, const xmlChar *SystemID)
  26657. {
  26658. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26659. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26660. (ctxt->user_sax->externalSubset != NULL))
  26661. ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
  26662. SystemID);
  26663. }
  26664. static xmlParserInputPtr
  26665. resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  26666. {
  26667. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26668. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26669. (ctxt->user_sax->resolveEntity != NULL))
  26670. return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
  26671. systemId));
  26672. return(NULL);
  26673. }
  26674. static xmlEntityPtr
  26675. getEntitySplit(void *ctx, const xmlChar *name)
  26676. {
  26677. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26678. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26679. (ctxt->user_sax->getEntity != NULL))
  26680. return(ctxt->user_sax->getEntity(ctxt->user_data, name));
  26681. return(NULL);
  26682. }
  26683. static xmlEntityPtr
  26684. getParameterEntitySplit(void *ctx, const xmlChar *name)
  26685. {
  26686. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26687. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26688. (ctxt->user_sax->getParameterEntity != NULL))
  26689. return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
  26690. return(NULL);
  26691. }
  26692. static void
  26693. entityDeclSplit(void *ctx, const xmlChar *name, int type,
  26694. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  26695. {
  26696. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26697. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26698. (ctxt->user_sax->entityDecl != NULL))
  26699. ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
  26700. systemId, content);
  26701. }
  26702. static void
  26703. attributeDeclSplit(void *ctx, const xmlChar * elem,
  26704. const xmlChar * name, int type, int def,
  26705. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  26706. {
  26707. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26708. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26709. (ctxt->user_sax->attributeDecl != NULL)) {
  26710. ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
  26711. def, defaultValue, tree);
  26712. } else {
  26713. xmlFreeEnumeration(tree);
  26714. }
  26715. }
  26716. static void
  26717. elementDeclSplit(void *ctx, const xmlChar *name, int type,
  26718. xmlElementContentPtr content)
  26719. {
  26720. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26721. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26722. (ctxt->user_sax->elementDecl != NULL))
  26723. ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
  26724. }
  26725. static void
  26726. notationDeclSplit(void *ctx, const xmlChar *name,
  26727. const xmlChar *publicId, const xmlChar *systemId)
  26728. {
  26729. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26730. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26731. (ctxt->user_sax->notationDecl != NULL))
  26732. ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
  26733. systemId);
  26734. }
  26735. static void
  26736. unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
  26737. const xmlChar *publicId, const xmlChar *systemId,
  26738. const xmlChar *notationName)
  26739. {
  26740. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26741. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26742. (ctxt->user_sax->unparsedEntityDecl != NULL))
  26743. ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
  26744. systemId, notationName);
  26745. }
  26746. static void
  26747. setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
  26748. {
  26749. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26750. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26751. (ctxt->user_sax->setDocumentLocator != NULL))
  26752. ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
  26753. }
  26754. static void
  26755. startDocumentSplit(void *ctx)
  26756. {
  26757. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26758. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26759. (ctxt->user_sax->startDocument != NULL))
  26760. ctxt->user_sax->startDocument(ctxt->user_data);
  26761. }
  26762. static void
  26763. endDocumentSplit(void *ctx)
  26764. {
  26765. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26766. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26767. (ctxt->user_sax->endDocument != NULL))
  26768. ctxt->user_sax->endDocument(ctxt->user_data);
  26769. }
  26770. static void
  26771. processingInstructionSplit(void *ctx, const xmlChar *target,
  26772. const xmlChar *data)
  26773. {
  26774. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26775. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26776. (ctxt->user_sax->processingInstruction != NULL))
  26777. ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
  26778. }
  26779. static void
  26780. commentSplit(void *ctx, const xmlChar *value)
  26781. {
  26782. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26783. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26784. (ctxt->user_sax->comment != NULL))
  26785. ctxt->user_sax->comment(ctxt->user_data, value);
  26786. }
  26787. /*
  26788. * Varargs error callbacks to the user application, harder ...
  26789. */
  26790. static void XMLCDECL
  26791. warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26792. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26793. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26794. (ctxt->user_sax->warning != NULL)) {
  26795. TODO
  26796. }
  26797. }
  26798. static void XMLCDECL
  26799. errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26800. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26801. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26802. (ctxt->user_sax->error != NULL)) {
  26803. TODO
  26804. }
  26805. }
  26806. static void XMLCDECL
  26807. fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26808. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26809. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26810. (ctxt->user_sax->fatalError != NULL)) {
  26811. TODO
  26812. }
  26813. }
  26814. /*
  26815. * Those are function where both the user handler and the schemas handler
  26816. * need to be called.
  26817. */
  26818. static void
  26819. charactersSplit(void *ctx, const xmlChar *ch, int len)
  26820. {
  26821. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26822. if (ctxt == NULL)
  26823. return;
  26824. if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
  26825. ctxt->user_sax->characters(ctxt->user_data, ch, len);
  26826. if (ctxt->ctxt != NULL)
  26827. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26828. }
  26829. static void
  26830. ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
  26831. {
  26832. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26833. if (ctxt == NULL)
  26834. return;
  26835. if ((ctxt->user_sax != NULL) &&
  26836. (ctxt->user_sax->ignorableWhitespace != NULL))
  26837. ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
  26838. if (ctxt->ctxt != NULL)
  26839. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26840. }
  26841. static void
  26842. cdataBlockSplit(void *ctx, const xmlChar *value, int len)
  26843. {
  26844. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26845. if (ctxt == NULL)
  26846. return;
  26847. if ((ctxt->user_sax != NULL) &&
  26848. (ctxt->user_sax->cdataBlock != NULL))
  26849. ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
  26850. if (ctxt->ctxt != NULL)
  26851. xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
  26852. }
  26853. static void
  26854. referenceSplit(void *ctx, const xmlChar *name)
  26855. {
  26856. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26857. if (ctxt == NULL)
  26858. return;
  26859. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26860. (ctxt->user_sax->reference != NULL))
  26861. ctxt->user_sax->reference(ctxt->user_data, name);
  26862. if (ctxt->ctxt != NULL)
  26863. xmlSchemaSAXHandleReference(ctxt->user_data, name);
  26864. }
  26865. static void
  26866. startElementNsSplit(void *ctx, const xmlChar * localname,
  26867. const xmlChar * prefix, const xmlChar * URI,
  26868. int nb_namespaces, const xmlChar ** namespaces,
  26869. int nb_attributes, int nb_defaulted,
  26870. const xmlChar ** attributes) {
  26871. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26872. if (ctxt == NULL)
  26873. return;
  26874. if ((ctxt->user_sax != NULL) &&
  26875. (ctxt->user_sax->startElementNs != NULL))
  26876. ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
  26877. URI, nb_namespaces, namespaces,
  26878. nb_attributes, nb_defaulted,
  26879. attributes);
  26880. if (ctxt->ctxt != NULL)
  26881. xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
  26882. URI, nb_namespaces, namespaces,
  26883. nb_attributes, nb_defaulted,
  26884. attributes);
  26885. }
  26886. static void
  26887. endElementNsSplit(void *ctx, const xmlChar * localname,
  26888. const xmlChar * prefix, const xmlChar * URI) {
  26889. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26890. if (ctxt == NULL)
  26891. return;
  26892. if ((ctxt->user_sax != NULL) &&
  26893. (ctxt->user_sax->endElementNs != NULL))
  26894. ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
  26895. if (ctxt->ctxt != NULL)
  26896. xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
  26897. }
  26898. /**
  26899. * xmlSchemaSAXPlug:
  26900. * @ctxt: a schema validation context
  26901. * @sax: a pointer to the original xmlSAXHandlerPtr
  26902. * @user_data: a pointer to the original SAX user data pointer
  26903. *
  26904. * Plug a SAX based validation layer in a SAX parsing event flow.
  26905. * The original @saxptr and @dataptr data are replaced by new pointers
  26906. * but the calls to the original will be maintained.
  26907. *
  26908. * Returns a pointer to a data structure needed to unplug the validation layer
  26909. * or NULL in case of errors.
  26910. */
  26911. xmlSchemaSAXPlugPtr
  26912. xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
  26913. xmlSAXHandlerPtr *sax, void **user_data)
  26914. {
  26915. xmlSchemaSAXPlugPtr ret;
  26916. xmlSAXHandlerPtr old_sax;
  26917. if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
  26918. return(NULL);
  26919. /*
  26920. * We only allow to plug into SAX2 event streams
  26921. */
  26922. old_sax = *sax;
  26923. if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
  26924. return(NULL);
  26925. if ((old_sax != NULL) &&
  26926. (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
  26927. ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
  26928. return(NULL);
  26929. /*
  26930. * everything seems right allocate the local data needed for that layer
  26931. */
  26932. ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
  26933. if (ret == NULL) {
  26934. return(NULL);
  26935. }
  26936. memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
  26937. ret->magic = XML_SAX_PLUG_MAGIC;
  26938. ret->schemas_sax.initialized = XML_SAX2_MAGIC;
  26939. ret->ctxt = ctxt;
  26940. ret->user_sax_ptr = sax;
  26941. ret->user_sax = old_sax;
  26942. if (old_sax == NULL) {
  26943. /*
  26944. * go direct, no need for the split block and functions.
  26945. */
  26946. ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
  26947. ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
  26948. /*
  26949. * Note that we use the same text-function for both, to prevent
  26950. * the parser from testing for ignorable whitespace.
  26951. */
  26952. ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
  26953. ret->schemas_sax.characters = xmlSchemaSAXHandleText;
  26954. ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
  26955. ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
  26956. ret->user_data = ctxt;
  26957. *user_data = ctxt;
  26958. } else {
  26959. /*
  26960. * for each callback unused by Schemas initialize it to the Split
  26961. * routine only if non NULL in the user block, this can speed up
  26962. * things at the SAX level.
  26963. */
  26964. if (old_sax->internalSubset != NULL)
  26965. ret->schemas_sax.internalSubset = internalSubsetSplit;
  26966. if (old_sax->isStandalone != NULL)
  26967. ret->schemas_sax.isStandalone = isStandaloneSplit;
  26968. if (old_sax->hasInternalSubset != NULL)
  26969. ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
  26970. if (old_sax->hasExternalSubset != NULL)
  26971. ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
  26972. if (old_sax->resolveEntity != NULL)
  26973. ret->schemas_sax.resolveEntity = resolveEntitySplit;
  26974. if (old_sax->getEntity != NULL)
  26975. ret->schemas_sax.getEntity = getEntitySplit;
  26976. if (old_sax->entityDecl != NULL)
  26977. ret->schemas_sax.entityDecl = entityDeclSplit;
  26978. if (old_sax->notationDecl != NULL)
  26979. ret->schemas_sax.notationDecl = notationDeclSplit;
  26980. if (old_sax->attributeDecl != NULL)
  26981. ret->schemas_sax.attributeDecl = attributeDeclSplit;
  26982. if (old_sax->elementDecl != NULL)
  26983. ret->schemas_sax.elementDecl = elementDeclSplit;
  26984. if (old_sax->unparsedEntityDecl != NULL)
  26985. ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
  26986. if (old_sax->setDocumentLocator != NULL)
  26987. ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
  26988. if (old_sax->startDocument != NULL)
  26989. ret->schemas_sax.startDocument = startDocumentSplit;
  26990. if (old_sax->endDocument != NULL)
  26991. ret->schemas_sax.endDocument = endDocumentSplit;
  26992. if (old_sax->processingInstruction != NULL)
  26993. ret->schemas_sax.processingInstruction = processingInstructionSplit;
  26994. if (old_sax->comment != NULL)
  26995. ret->schemas_sax.comment = commentSplit;
  26996. if (old_sax->warning != NULL)
  26997. ret->schemas_sax.warning = warningSplit;
  26998. if (old_sax->error != NULL)
  26999. ret->schemas_sax.error = errorSplit;
  27000. if (old_sax->fatalError != NULL)
  27001. ret->schemas_sax.fatalError = fatalErrorSplit;
  27002. if (old_sax->getParameterEntity != NULL)
  27003. ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
  27004. if (old_sax->externalSubset != NULL)
  27005. ret->schemas_sax.externalSubset = externalSubsetSplit;
  27006. /*
  27007. * the 6 schemas callback have to go to the splitter functions
  27008. * Note that we use the same text-function for ignorableWhitespace
  27009. * if possible, to prevent the parser from testing for ignorable
  27010. * whitespace.
  27011. */
  27012. ret->schemas_sax.characters = charactersSplit;
  27013. if ((old_sax->ignorableWhitespace != NULL) &&
  27014. (old_sax->ignorableWhitespace != old_sax->characters))
  27015. ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
  27016. else
  27017. ret->schemas_sax.ignorableWhitespace = charactersSplit;
  27018. ret->schemas_sax.cdataBlock = cdataBlockSplit;
  27019. ret->schemas_sax.reference = referenceSplit;
  27020. ret->schemas_sax.startElementNs = startElementNsSplit;
  27021. ret->schemas_sax.endElementNs = endElementNsSplit;
  27022. ret->user_data_ptr = user_data;
  27023. ret->user_data = *user_data;
  27024. *user_data = ret;
  27025. }
  27026. /*
  27027. * plug the pointers back.
  27028. */
  27029. *sax = &(ret->schemas_sax);
  27030. ctxt->sax = *sax;
  27031. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27032. xmlSchemaPreRun(ctxt);
  27033. return(ret);
  27034. }
  27035. /**
  27036. * xmlSchemaSAXUnplug:
  27037. * @plug: a data structure returned by xmlSchemaSAXPlug
  27038. *
  27039. * Unplug a SAX based validation layer in a SAX parsing event flow.
  27040. * The original pointers used in the call are restored.
  27041. *
  27042. * Returns 0 in case of success and -1 in case of failure.
  27043. */
  27044. int
  27045. xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
  27046. {
  27047. xmlSAXHandlerPtr *sax;
  27048. void **user_data;
  27049. if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
  27050. return(-1);
  27051. plug->magic = 0;
  27052. xmlSchemaPostRun(plug->ctxt);
  27053. /* restore the data */
  27054. sax = plug->user_sax_ptr;
  27055. *sax = plug->user_sax;
  27056. if (plug->user_sax != NULL) {
  27057. user_data = plug->user_data_ptr;
  27058. *user_data = plug->user_data;
  27059. }
  27060. /* free and return */
  27061. xmlFree(plug);
  27062. return(0);
  27063. }
  27064. /**
  27065. * xmlSchemaValidateStream:
  27066. * @ctxt: a schema validation context
  27067. * @input: the input to use for reading the data
  27068. * @enc: an optional encoding information
  27069. * @sax: a SAX handler for the resulting events
  27070. * @user_data: the context to provide to the SAX handler.
  27071. *
  27072. * Validate an input based on a flow of SAX event from the parser
  27073. * and forward the events to the @sax handler with the provided @user_data
  27074. * the user provided @sax handler must be a SAX2 one.
  27075. *
  27076. * Returns 0 if the document is schemas valid, a positive error code
  27077. * number otherwise and -1 in case of internal or API error.
  27078. */
  27079. int
  27080. xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
  27081. xmlParserInputBufferPtr input, xmlCharEncoding enc,
  27082. xmlSAXHandlerPtr sax, void *user_data)
  27083. {
  27084. xmlSchemaSAXPlugPtr plug = NULL;
  27085. xmlSAXHandlerPtr old_sax = NULL;
  27086. xmlParserCtxtPtr pctxt = NULL;
  27087. xmlParserInputPtr inputStream = NULL;
  27088. int ret;
  27089. if ((ctxt == NULL) || (input == NULL))
  27090. return (-1);
  27091. /*
  27092. * prepare the parser
  27093. */
  27094. pctxt = xmlNewParserCtxt();
  27095. if (pctxt == NULL)
  27096. return (-1);
  27097. old_sax = pctxt->sax;
  27098. pctxt->sax = sax;
  27099. pctxt->userData = user_data;
  27100. #if 0
  27101. if (options)
  27102. xmlCtxtUseOptions(pctxt, options);
  27103. #endif
  27104. pctxt->linenumbers = 1;
  27105. inputStream = xmlNewIOInputStream(pctxt, input, enc);;
  27106. if (inputStream == NULL) {
  27107. ret = -1;
  27108. goto done;
  27109. }
  27110. inputPush(pctxt, inputStream);
  27111. ctxt->parserCtxt = pctxt;
  27112. ctxt->input = input;
  27113. /*
  27114. * Plug the validation and launch the parsing
  27115. */
  27116. plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
  27117. if (plug == NULL) {
  27118. ret = -1;
  27119. goto done;
  27120. }
  27121. ctxt->input = input;
  27122. ctxt->enc = enc;
  27123. ctxt->sax = pctxt->sax;
  27124. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27125. ret = xmlSchemaVStart(ctxt);
  27126. if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
  27127. ret = ctxt->parserCtxt->errNo;
  27128. if (ret == 0)
  27129. ret = 1;
  27130. }
  27131. done:
  27132. ctxt->parserCtxt = NULL;
  27133. ctxt->sax = NULL;
  27134. ctxt->input = NULL;
  27135. if (plug != NULL) {
  27136. xmlSchemaSAXUnplug(plug);
  27137. }
  27138. /* cleanup */
  27139. if (pctxt != NULL) {
  27140. pctxt->sax = old_sax;
  27141. xmlFreeParserCtxt(pctxt);
  27142. }
  27143. return (ret);
  27144. }
  27145. /**
  27146. * xmlSchemaValidateFile:
  27147. * @ctxt: a schema validation context
  27148. * @filename: the URI of the instance
  27149. * @options: a future set of options, currently unused
  27150. *
  27151. * Do a schemas validation of the given resource, it will use the
  27152. * SAX streamable validation internally.
  27153. *
  27154. * Returns 0 if the document is valid, a positive error code
  27155. * number otherwise and -1 in case of an internal or API error.
  27156. */
  27157. int
  27158. xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
  27159. const char * filename,
  27160. int options ATTRIBUTE_UNUSED)
  27161. {
  27162. int ret;
  27163. xmlParserInputBufferPtr input;
  27164. if ((ctxt == NULL) || (filename == NULL))
  27165. return (-1);
  27166. input = xmlParserInputBufferCreateFilename(filename,
  27167. XML_CHAR_ENCODING_NONE);
  27168. if (input == NULL)
  27169. return (-1);
  27170. ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
  27171. NULL, NULL);
  27172. return (ret);
  27173. }
  27174. /**
  27175. * xmlSchemaValidCtxtGetParserCtxt:
  27176. * @ctxt: a schema validation context
  27177. *
  27178. * allow access to the parser context of the schema validation context
  27179. *
  27180. * Returns the parser context of the schema validation context or NULL
  27181. * in case of error.
  27182. */
  27183. xmlParserCtxtPtr
  27184. xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
  27185. {
  27186. if (ctxt == NULL)
  27187. return(NULL);
  27188. return (ctxt->parserCtxt);
  27189. }
  27190. #define bottom_xmlschemas
  27191. #include "elfgcchack.h"
  27192. #endif /* LIBXML_SCHEMAS_ENABLED */